Wywoływanie metod klasy nadrzędnej
Część sekcji Programowanie obiektowe ścieżki Lua w Coddy. Lekcja 38 z 70.
Czasami całkowite nadpisanie metody nie jest tym, czego chcesz. Zamiast tego możesz chcieć rozszerzyć zachowanie klasy nadrzędnej: zrobić to, co robi klasa nadrzędna, a następnie dodać coś jeszcze. Aby to osiągnąć, możesz wywołać metodę klasy nadrzędnej bezpośrednio z nadpisanej metody klasy potomnej.
Ta technika wykorzystuje składnię kropkową z nazwą klasy nadrzędnej, jawnie przekazując self jako pierwszy argument:
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog rozszerza zachowanie klasy nadrzędnej
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
function Dog:speak()
Animal.speak(self) -- Najpierw wywołaj metodę klasy nadrzędnej
print(self.name .. " wags tail happily")
endKluczowa linia to Animal.speak(self). Używając składni kropkowej dla klasy nadrzędnej i przekazując ręcznie self, wywołujemy oryginalną metodę, zanim dodamy własne zachowanie:
local buddy = Dog:new("Buddy")
buddy:speak()
-- Wynik:
-- Buddy wydaje dźwięk
-- Buddy radośnie macha ogonemTen wzorzec jest przydatny, gdy metoda klasy nadrzędnej wykonuje ważną pracę, której nie chcesz powielać. Klasa potomna może uruchomić logikę klasy nadrzędnej na początku, na końcu, a nawet w środku własnego kodu, dając ci pełną kontrolę nad tym, jak łączą się zachowania.
Wyzwanie
ŁatwyZbudujmy system powitań, w którym FormalPerson rozszerza zachowanie zwykłej klasy Person! Zamiast całkowicie zastępować sposób, w jaki dana osoba się przedstawia, formalna wersja najpierw wykona standardowe przedstawienie, a następnie doda uprzejmy akcent.
Rozmieścisz swój kod w trzech plikach:
Person.lua: Twoja klasa bazowa z konstruktorem:new(name), który zapisuje imię danej osoby. Dodaj metodę:introduce(), która wyświetla imię danej osoby, a po nimsays hi. To zachowanie bazowe, które zostanie rozszerzone.FormalPerson.lua: Klasa potomna dziedzicząca po Person. Jej konstruktor powinien wywołać konstruktor klasy nadrzędnej, aby obsłużyć imię. Nadpisz metodę:introduce(), ale zamiast całkowicie zastępować zachowanie klasy nadrzędnej, najpierw wywołaj metodę klasy nadrzędnej za pomocąPerson.introduce(self), a następnie wyświetl dodatkowy wiersz z imieniem danej osoby, po którym następujebows politely.main.lua: Załaduj moduł FormalPerson, wczytaj imię, utwórz instancję FormalPerson i wywołaj:introduce(), aby zobaczyć połączone działanie obu metod.
Otrzymasz jedno dane wejściowe: imię danej osoby.
Po wywołaniu :introduce() na obiekcie FormalPerson powinny zostać wyświetlone dwa wiersze: pierwszy z metody klasy nadrzędnej, drugi z dodatku klasy potomnej:
{name} says hi
{name} bows politelyNa przykład, jeśli dane wejściowe to Eleanor, wynik powinien być następujący:
Eleanor says hi
Eleanor bows politelyKluczowy wniosek jest taki, że FormalPerson nie powiela logiki "says hi". Zleca wykonanie tej pracy metodzie klasy nadrzędnej, a następnie dodaje własne, unikalne zachowanie. Dzięki temu kod jest przejrzysty, a także pokazuje, jak klasy potomne mogą rozszerzać funkcjonalność klas nadrzędnych, zamiast ją zastępować!
Spróbuj swoich sił
-- main.lua: Punkt wejścia systemu powitań
local FormalPerson = require('FormalPerson')
-- Odczytaj imię osoby z wejścia
local name = io.read()
-- TODO: Utwórz instancję FormalPerson o podanym imieniu
-- TODO: Wywołaj metodę introduce na instancji FormalPerson
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