Menu
CoddyTech

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

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

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

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

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"  -- Общее для всех Dog

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

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

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

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

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

challenge icon

Задание

Легко

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

Ты разместишь код в трёх файлах:

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

Ты получишь два входных значения:

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

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

  1. name первого дракона
  2. color первого дракона
  3. name второго дракона
  4. color второго дракона
  5. element первого дракона (общий атрибут класса Dragon)
  6. element второго дракона (общий атрибут класса Dragon)
  7. world первого дракона (общий атрибут класса Creature)

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

Smaug
red
Draco
gold
fire
fire
Fantasy Realm

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

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

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

local Dragon = require('Dragon')

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

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

-- TODO: Разберите вторые входные данные, чтобы извлечь имя и цвет

-- TODO: Создайте первого дракона, указав его имя и цвет

-- TODO: Создайте второго дракона, указав его имя и цвет

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

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

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

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