Dodawanie metod potomnych
Część sekcji Programowanie obiektowe ścieżki Lua w Coddy. Lekcja 34 z 70.
Dziedziczenie pozwala klasom potomnym korzystać z metod klas nadrzędnych, ale prawdziwa siła tkwi w dodawaniu nowych metod, które ma tylko klasa potomna. Dog potrafi robić wszystko, co Animal, a do tego rzeczy charakterystyczne dla psów, takie jak szczekanie.
Dodanie metody specyficznej dla klasy potomnej jest proste: wystarczy zdefiniować ją w tabeli klasy potomnej. Ponieważ instancje najpierw szukają metod we własnej klasie, znajdą nową metodę bez wpływu na klasę nadrzędną.
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 dziedziczy po 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
-- Nowa metoda dostępna tylko w Dog
function Dog:bark()
print(self.name .. " says: Woof!")
endTeraz instancje Dog mogą używać zarówno odziedziczonych, jak i unikalnych metod:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Wynik: Buddy oddycha (odziedziczona metoda)
buddy:bark() -- Wynik: Buddy mówi: Hau! (metoda dostępna tylko w klasie potomnej)Klasa nadrzędna pozostaje bez zmian: wywołanie :bark() na zwykłym obiekcie Animal zakończyłoby się błędem, ponieważ ta metoda tam nie istnieje. W ten sposób dziedziczenie pozwala wyspecjalizować zachowanie, zachowując wspólną funkcjonalność w jednym miejscu.
Wyzwanie
ŁatwyZbudujmy hierarchię zwierząt, w której koty mają własną wyjątkową umiejętność! Utworzysz klasę nadrzędną Pet i klasę podrzędną Cat, w której Cat dziedziczy wszystko z Pet, ale ma też unikatową metodę, z której mogą korzystać tylko koty.
Rozmieścisz swój kod w trzech plikach:
Pet.lua: Zdefiniuj klasę nadrzędną z konstruktorem:new(name), który zapisuje imię zwierzęcia. Dodaj metodę:greet(), która wypisuje imię zwierzęcia, a po nimsays hello. Zastosuj standardowy wzorzec klasy i zwróć klasę.Cat.lua: Zdefiniuj klasę podrzędną, która dziedziczy po Pet. Konstruktor:new(name)klasy Cat powinien wywołać konstruktor klasy nadrzędnej, aby zainicjować imię, a następnie ponownie powiązać metatabelę z Cat. Dodaj specyficzną dla klasy podrzędnej metodę:purr(), która wypisuje imię kota, a po nimpurrs contentedly. Ta metoda istnieje tylko w Cat: Pet jej nie ma!main.lua: Zaimportuj moduł Cat, odczytaj imię z wejścia, utwórz instancję Cat i pokaż, że może używać zarówno odziedziczonej metody:greet(), jak i własnej unikatowej metody:purr().
Otrzymasz jedno dane wejściowe: imię kota.
W pliku głównym utwórz obiekt Cat o podanym imieniu, a następnie wywołaj :greet(), po czym :purr() w osobnych wierszach.
Na przykład, jeśli dane wejściowe to Whiskers, dane wyjściowe powinny wyglądać tak:
Whiskers says hello
Whiskers purrs contentedlyPierwszy wiersz pochodzi z odziedziczonej metody :greet() zdefiniowanej w Pet, a drugi z metody :purr(), która istnieje tylko w Cat. To pokazuje, jak klasy podrzędne mogą robić wszystko to, co ich klasa nadrzędna, a także wykonywać własne, wyspecjalizowane działania!
Spróbuj swoich sił
-- main.lua: Utwórz obiekt Cat i zademonstruj dziedziczenie
local Cat = require('Cat')
-- Odczytaj imię kota z danych wejściowych
local name = io.read()
-- TODO: Utwórz instancję Cat o podanym imieniu
-- TODO: Wywołaj odziedziczoną metodę :greet() (z Pet)
-- TODO: Wywołaj metodę :purr() specyficzną dla Cat
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Koncepcja „self”
Tabele z funkcjamiJawne „self”Składnia z dwukropkiemKropka czy dwukropekPodsumowanie — poruszający się punkt4Projekt: Bank cyfrowy
Konfiguracja projektuMetoda wpłaty7Polimorfizm i nadpisywanie
Nadpisywanie metodWywoływanie metod klasy nadrzędnejTypowanie kaczeWspólny interfejsSprawdzanie typuPodsumowanie — role pracowników10Projekt: Menedżer kształtów
Konfiguracja projektuKlasa prostokątaKlasa kołaMetoda obwoduKolekcja kształtówPole całkowiteFiltrowanie kształtów2Wzorzec prototypu klasy
Koncepcja prototypuŁączenie za pomocą __indexKonstruktor :new()Inicjalizacja atrybutówNiezależne instancjePodsumowanie – fabryka samochodów5Przeciążanie operatorów w OOP
Dodawanie obiektówOdejmowanie obiektówŁączenie obiektówPorównywanie obiektów (<, >)Powtórka — działania na portfelu8Hermetyzacja
Konwencje nazewnictwaDomknięcia dla prywatnościDostęp za pomocą domknięćTabele tylko do odczytuLogika walidacjiPodsumowanie — bezpieczny sejf11Wzorce projektowe (podstawy)
Funkcje fabrykująceTabela SingletonWzorzec iteratoraObserwator (nasłuchujący)Powtórka — fabryka loggera3Stan i zachowanie obiektu
Zmienne instancjiMetody dostępoweMetody ustawiająceWłaściwości obliczaneFormatowanie ciągów znakówSprawdzanie równościPodsumowanie – ocena ucznia6Podstawy dziedziczenia
Konfiguracja dziedziczeniaDziedziczenie metodRozszerzanie konstruktoraDodawanie metod potomnychWspólne i unikalne elementyPowtórka — hierarchia kształtówPoćwicz samodzielnie: Kompilator Lua online