Menu
Coddy logo textTech

Добавление дочерних методов

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

Наследование позволяет классам child получать доступ к методам parent, но настоящая сила заключается в добавлении новых methods, которые есть только у child. Dog может делать всё, что может Animal, а также выполнять уникальные для собак действия, например лаять.

Добавить метод, специфичный для child, просто: достаточно определить его в таблице class child. Поскольку экземпляры сначала ищут методы в своём собственном class, они найдут новый метод, не затрагивая parent.

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:breathe()
    print(self.name .. " is breathing")
end

-- Dog наследует от Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

-- Новый метод только в Dog
function Dog:bark()
    print(self.name .. " says: Woof!")
end

Теперь экземпляры Dog могут использовать как унаследованные, так и уникальные методы:

local buddy = Dog:new("Buddy")
buddy:breathe()  -- Вывод: Buddy дышит (унаследовано)
buddy:bark()     -- Вывод: Buddy говорит: Woof! (только дочерний)

Родительский класс остаётся неизменным: вызов :bark() у обычного Animal завершился бы ошибкой, поскольку такого method там не существует. Так inheritance позволяет специализировать поведение, сохраняя общую функциональность в одном месте.

challenge icon

Задание

Легко

Давайте создадим иерархию питомцев, где у кошек есть особая способность! Вы создадите родительский класс Pet и дочерний класс Cat, в котором Cat наследует всё от Pet, но также имеет уникальный метод, который могут выполнять только кошки.

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

  • Pet.lua: Определите родительский класс с конструктором :new(name), который сохраняет имя питомца. Добавьте метод :greet(), выводящий имя питомца, за которым следует says hello. Настройте стандартный шаблон класса и верните класс.
  • Cat.lua: Определите дочерний класс, который наследует от Pet. Конструктор :new(name) вашего Cat должен вызвать родительский конструктор, чтобы инициализировать имя, а затем повторно связать метатаблицу с Cat. Добавьте специфичный для дочернего класса метод :purr(), который выводит имя кошки, за которым следует purrs contentedly. Этот метод существует только в Cat: у Pet его нет!
  • main.lua: Подключите свой модуль Cat, прочитайте имя из input, создайте экземпляр Cat и продемонстрируйте, что он может использовать как унаследованный метод :greet(), так и собственный уникальный метод :purr().

На вход будет подано одно значение: имя кошки.

В основном файле создайте Cat с указанным именем, затем вызовите :greet(), а после него — :purr() на отдельных строках.

Например, если на вход подано Whiskers, результат должен быть таким:

Whiskers says hello
Whiskers purrs contentedly

Первая строка получается благодаря унаследованному методу :greet(), определённому в Pet, а вторая — благодаря методу :purr(), который существует только в Cat. Это демонстрирует, как дочерние классы могут делать всё, что умеет их родитель, а также выполнять собственные специализированные действия!

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

-- main.lua: Создать Cat и продемонстрировать наследование

local Cat = require('Cat')

-- Прочитать имя кота из ввода
local name = io.read()

-- TODO: Создать экземпляр Cat с заданным именем

-- TODO: Вызвать унаследованный метод :greet() (из Pet)

-- TODO: Вызвать специфичный для Cat метод :purr()
quiz iconПроверьте себя

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

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

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