Menu
Coddy logo textTech

Nadpisywanie metod

Część sekcji Programowanie obiektowe ścieżki Lua w Coddy. Lekcja 37 z 70.

Do tej pory klasy potomne dziedziczyły metody klas nadrzędnych i dodawały nowe. Ale co, jeśli klasa potomna potrzebuje tej samej nazwy metody, ale innego działania? Nazywa się to przesłanianiem metod.

Gdy definiujesz metodę w klasie potomnej o tej samej nazwie co metoda w klasie nadrzędnej, pierwszeństwo ma wersja z klasy potomnej. Łańcuch wyszukiwania w Lua najpierw sprawdza klasę potomną i jeśli znajdzie tam metodę, przestaje szukać.

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 nadpisuje speak()
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()
    print(self.name .. " barks: Woof!")
end

Teraz każda klasa reaguje inaczej na to samo wywołanie metody:

local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")

generic:speak()  -- Wynik: Creature wydaje dźwięk
buddy:speak()    -- Wynik: Buddy szczeka: Hau!

Metoda :speak() klasy Dog całkowicie zastępuje wersję odziedziczoną po klasie nadrzędnej w przypadku instancji Dog. Dzięki temu możesz tworzyć wyspecjalizowane zachowania, zachowując spójny interfejs: każde zwierzę może :speak(), ale każdy gatunek robi to inaczej.

challenge icon

Wyzwanie

Łatwy

Stwórzmy małe królestwo zwierząt, w którym różne stworzenia odzywają się na swój wyjątkowy sposób! Utworzysz klasę bazową Animal oraz dwie klasy potomne: Cat i Cow. Każda z nich przesłoni metodę :speak() klasy bazowej, nadając jej własne działanie.

Rozmieścisz swój kod w czterech plikach:

  • Animal.lua: Twoja klasa bazowa z konstruktorem :new(name), który zapisuje imię zwierzęcia. Dodaj metodę :speak(), która wypisuje imię zwierzęcia, a po nim makes a sound. To domyślne działanie, które klasy potomne przesłonią.
  • Cat.lua: Klasa potomna dziedzicząca po Animal. Jej konstruktor :new(name) powinien wywołać konstruktor klasy bazowej, a następnie ponownie powiązać metatabelę z Cat. Przesłoń metodę :speak(), aby koty odzywały się inaczej: wypisz imię kota, a po nim meows: Meow!
  • Cow.lua: Kolejna klasa potomna dziedzicząca po Animal. Skonfiguruj konstruktor tak samo jak w Cat. Przesłoń metodę :speak(), aby krowy wypisywały swoje imię, a po nim moos: Moo!
  • main.lua: Połącz wszystko w całość! Odczytaj z wejścia dwa imiona, utwórz Cat z pierwszym imieniem i Cow z drugim, a następnie wywołaj :speak() dla każdego z nich, aby pokazać, że ta sama nazwa metody daje różne wyniki w zależności od klasy.

Otrzymasz dwa dane wejściowe:

  1. Imię kota
  2. Imię krowy

W pliku głównym utwórz oba zwierzęta i najpierw wywołaj :speak() dla kota, a potem dla krowy.

Na przykład, jeśli danymi wejściowymi są Whiskers i Bessie, wynikiem powinno być:

Whiskers meows: Meow!
Bessie moos: Moo!

Zauważ, że oba zwierzęta reagują na to samo wywołanie metody :speak(), ale każde wypisuje tekst właściwy dla swojego typu. Wersja Cat całkowicie zastępuje ogólne działanie klasy bazowej makes a sound, podobnie jak wersja Cow. To właśnie przesłanianie metod: ten sam interfejs, różne implementacje!

Spróbuj swoich sił

-- main.lua: Połącz wszystko w całość

local Cat = require('Cat')
local Cow = require('Cow')

-- Odczytaj dane wejściowe
local catName = io.read()
local cowName = io.read()

-- TODO: Utwórz obiekt Cat z pierwszym imieniem

-- TODO: Utwórz obiekt Cow z drugim imieniem

-- TODO: Wywołaj :speak() najpierw dla kota, a potem dla krowy
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Lua online