В прошлый раз мы научились создавать объекты в lua и вызывать их методы. Нами был создан класс ClassA (хорошо, не класс, а объект-прототип), имеющий одно поле (Name) и два метода (Metod1, Metod2). Были созданы два экземпляра объектов и вызваны их методы.
Сегодня мы попытаемся создать наследника от ClassA, добавим ему еще одно поле, унаследуем один из методов без изменений, а второй переопределим.
Так же как и класс-родитель, наследник изначально представляет собой пустую таблицу:
ClassB={}
ClassB.__index=ClassB
setmetatable(ClassB,ClassA)После выполнения setmetatable, ClassB внешне будет представлять собой точную копию ClassA, т. е. унаследует все его методы.Изменения начнем с конструктора
function ClassB:new(_Name,_Size)
local obj=ClassA:new(_Name)
obj.Size=_Size
setmetatable(obj,self)
print('Constructor ClassB for '..obj.Name)
return obj
endКаковы отличия в конструкторах родителя и наследника? Как видим, для создания объекта наследник использует конструктор родителя, а не создает объект «с нуля». Это конечно не обязательно, но такова классика. Другое отличие — новое поле, которое будет хранить воображаемый размер нашего объекта.Переходим к методам. Metod1, как и договаривались оставляем нетронутым, а вот Metod2 переопределим.
function ClassB:Metod2()
ClassA.Metod2(self) --inherited
print('Metod2 of ClassB for '..self.Name..'. Size is '..self.Size)
endТут я показал как из метода объекта-наследника вызвать метод объекта-родителя. Но это тоже при необходимости.Вот собственно и всё.
Помимо ранее созданных объектов ClassA, создаем еще два экземпляра нового объекта
objects={}
for i = 1,2 do
objects[i] = ClassA:new('Object#'..i)
end
for i = 3,4 do
objects[i] = ClassB:new('Object#'..i, i*i)
endИ посмотрим что получилось
for i=1,4 do
objects[i]:Metod1()
objects[i]:Metod2()
endУ меня получилось вот что:[ATTACH]116[/ATTACH]
Обращаю внимание, что для объектов 3 и 4 конструктор и Metod2 выполняются дважды — сначала от ClassA, затем от ClassB.
Мы рассмотрели такие особенности ООП как наследование и полиморфизм. А вот как реализовать на lua сокрытие данных объекта от доступа извне (по моему, это называется инкапсуляцией) я пока не знаю. Если знаете — пишите.
Для тех кто все таки решил попробовать себя в объектно-ориентированном программировании, напоминаю — следите за пунктуацией. Имя поля отделяем точкой, имя метода — двоеточием. Это важно.