Добавление дочерних методов
Часть раздела Объектно-ориентированное программирование путешествия по 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 позволяет специализировать поведение, сохраняя общую функциональность в одном месте.
Задание
ЛегкоДавайте создадим иерархию питомцев, где у кошек есть особая способность! Вы создадите родительский класс 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()
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигурПотренируйтесь самостоятельно: Онлайн-компилятор Lua