Menu
Coddy logo textTech

Общее и уникальное

Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 35 из 70.

При работе с наследованием важно понимать, где находится каждый фрагмент данных. Некоторые attributes являются общими: defined в родительском классе и доступные всем дочерним объектам. Другие являются уникальными: созданными специально в child class или экземпляре.

Рассмотрим эту иерархию:

local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia"  -- Общее: определено на классе

function Animal:new(name)
    local obj = {name = name}  -- Уникальное: хранится на каждом экземпляре
    setmetatable(obj, Animal)
    return obj
end
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark"  -- Общий для всех Dogs

function Dog:new(name, breed)
    local obj = Animal.new(Animal, name)
    obj.breed = breed  -- Уникальный: у каждого Dog свой breed
    setmetatable(obj, Dog)
    return obj
end

Когда вы создаёте экземпляр Dog, некоторые значения существуют непосредственно в объекте, тогда как другие found через цепочку поиска:

local rex = Dog:new("Rex", "German Shepherd")

-- Уникально для этого экземпляра (хранится на rex)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"
-- Общий (найден через lookup)
print(rex.sound)   -- "bark" (из Dog)
print(rex.kingdom) -- "Animalia" (из Animal)

Ключевое различие: поля, присвоенные obj в конструкторах, уникальны для каждого экземпляра, тогда как поля, defined directly в таблицах class, являются общими для all экземпляров этого class и его потомков.

challenge icon

Задание

Легко

Давайте исследуем, как данные проходят через иерархию наследования, создав систему классов Creature и Dragon. Вы наглядно увидите, какие атрибуты являются общими для всех экземпляров, а какие уникальны для каждого отдельного объекта.

Вы организуете код в трех файлах:

  • Creature.lua: определите родительский class с общим атрибутом уровня class world = "Fantasy Realm", который используют все существа. Добавьте конструктор :new(name), сохраняющий имя существа как атрибут экземпляра.
  • Dragon.lua: определите дочерний class, который inherits от Creature. Добавьте общий атрибут уровня class element = "fire", который используют все драконы. Ваш конструктор :new(name, color) должен вызвать родительский конструктор для имени, а затем добавить color как уникальный атрибут экземпляра для каждого дракона.
  • main.lua: создайте двух разных драконов и изучите их атрибуты, чтобы продемонстрировать различие между общими и уникальными данными.

Вы получите два входных значения:

  1. Имя и цвет First дракона, разделенные запятой (например, Smaug,red)
  2. Имя и цвет Second дракона, разделенные запятой (например, Draco,gold)

В основном файле создайте обоих драконов с соответствующими именами и цветами. Затем выведите следующую информацию в этом exact порядке:

  1. name First дракона
  2. color First дракона
  3. name Second дракона
  4. color Second дракона
  5. element First дракона (общий атрибут из Dragon class)
  6. element Second дракона (общий атрибут из Dragon class)
  7. world First дракона (общий атрибут из Creature class)

Например, если входными данными являются Smaug,red и Draco,gold, результат должен быть таким:

Smaug
red
Draco
gold
fire
fire
Fantasy Realm

Обратите внимание, что name и color различаются у каждого дракона (уникальные атрибуты экземпляра), тогда как element и world одинаковы для обоих (общие атрибуты class, найденные через цепочку поиска).

Попробуйте сами

-- main.lua: Создать драконов и продемонстрировать общие и уникальные атрибуты

local Dragon = require('Dragon')

-- Прочитать ввод для первого дракона (name,color)
local input1 = io.read()
-- Прочитать ввод для второго дракона (name,color)
local input2 = io.read()

-- TODO: Разобрать первый ввод, чтобы извлечь name и color
-- Подсказка: Используйте string.match с шаблоном "([^,]+),([^,]+)"

-- TODO: Разобрать второй ввод, чтобы извлечь name и color

-- TODO: Создать первого дракона с его name и color

-- TODO: Создать второго дракона с его name и color

-- TODO: Вывести следующее в порядке:
-- 1. Имя первого дракона
-- 2. Цвет первого дракона
-- 3. Имя второго дракона
-- 4. Цвет второго дракона
-- 5. Элемент первого дракона (общий из класса Dragon)
-- 6. Элемент второго дракона (общий из класса Dragon)
-- 7. Мир первого дракона (общий из класса Creature)
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Lua