Menu
Coddy logo textTech

Wspólne i unikalne elementy

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

Podczas pracy z dziedziczeniem ważne jest, aby rozumieć, gdzie znajduje się każdy element danych. Niektóre atrybuty są współdzielone: zdefiniowane w klasie nadrzędnej i dostępne dla wszystkich klas potomnych. Inne są unikalne: utworzone specjalnie w klasie potomnej lub instancji.

Rozważ tę hierarchię:

local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia"  -- Wspólne: zdefiniowane w klasie

function Animal:new(name)
    local obj = {name = name}  -- Unikalne: przechowywane w każdej instancji
    setmetatable(obj, Animal)
    return obj
end
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark"  -- Wspólne dla wszystkich obiektów Dog

function Dog:new(name, breed)
    local obj = Animal.new(Animal, name)
    obj.breed = breed  -- Unikalne: każdy obiekt Dog ma własną rasę
    setmetatable(obj, Dog)
    return obj
end

Gdy tworzysz instancję Dog, niektóre wartości znajdują się bezpośrednio w obiekcie, a inne są wyszukiwane w łańcuchu wyszukiwania:

local rex = Dog:new("Rex", "German Shepherd")

-- Unikalne dla tej instancji (przechowywane w rex)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"
-- Współdzielone (znalezione przez wyszukiwanie)
print(rex.sound)   -- "bark" (z Dog)
print(rex.kingdom) -- "Animalia" (z Animal)

Kluczowa różnica: pola przypisane do obj w konstruktorach są unikalne dla każdej instancji, natomiast pola zdefiniowane bezpośrednio w tabelach klas są współdzielone przez wszystkie instancje tej klasy i jej klas potomnych.

challenge icon

Wyzwanie

Łatwy

Przyjrzyjmy się, jak dane przepływają przez hierarchię dziedziczenia, tworząc system klas Creature i Dragon. Zobaczysz na własne oczy, które atrybuty są współdzielone przez wszystkie instancje, a które są unikalne dla każdego obiektu.

Rozmieścisz swój kod w trzech plikach:

  • Creature.lua: Zdefiniuj klasę nadrzędną ze współdzielonym atrybutem na poziomie klasy world = "Fantasy Realm", który jest wspólny dla wszystkich stworzeń. Dodaj konstruktor :new(name), który zapisuje imię stworzenia jako atrybut instancji.
  • Dragon.lua: Zdefiniuj klasę podrzędną dziedziczącą po Creature. Dodaj współdzielony atrybut na poziomie klasy element = "fire", który jest wspólny dla wszystkich smoków. Konstruktor :new(name, color) powinien wywołać konstruktor klasy nadrzędnej, przekazując imię, a następnie dodać color jako unikalny atrybut instancji każdego smoka.
  • main.lua: Utwórz dwa różne smoki i sprawdź ich atrybuty, aby pokazać różnicę między danymi współdzielonymi a unikalnymi.

Otrzymasz dwa wejścia:

  1. Imię i kolor pierwszego smoka, oddzielone przecinkiem (np. Smaug,red)
  2. Imię i kolor drugiego smoka, oddzielone przecinkiem (np. Draco,gold)

W pliku głównym utwórz oba smoki, używając odpowiednich imion i kolorów. Następnie wypisz poniższe informacje dokładnie w tej kolejności:

  1. name pierwszego smoka
  2. color pierwszego smoka
  3. name drugiego smoka
  4. color drugiego smoka
  5. element pierwszego smoka (współdzielony z klasy Dragon)
  6. element drugiego smoka (współdzielony z klasy Dragon)
  7. world pierwszego smoka (współdzielony z klasy Creature)

Na przykład, jeśli wejściami są Smaug,red i Draco,gold, wynikiem powinno być:

Smaug
red
Draco
gold
fire
fire
Fantasy Realm

Zwróć uwagę, że name i color różnią się dla każdego smoka (unikalne atrybuty instancji), natomiast element i world są takie same dla obu (współdzielone atrybuty klasy odnajdywane w łańcuchu wyszukiwania).

Spróbuj swoich sił

-- main.lua: Utwórz smoki i pokaż atrybuty wspólne oraz unikalne

local Dragon = require('Dragon')

-- Odczytaj dane pierwszego smoka (imię, kolor)
local input1 = io.read()
-- Odczytaj dane drugiego smoka (imię, kolor)
local input2 = io.read()

-- TODO: Przeanalizuj pierwsze dane wejściowe, aby wyodrębnić imię i kolor
-- Wskazówka: Użyj string.match ze wzorcem "([^,]+),([^,]+)"

-- TODO: Przeanalizuj drugie dane wejściowe, aby wyodrębnić imię i kolor

-- TODO: Utwórz pierwszego smoka, podając jego imię i kolor

-- TODO: Utwórz drugiego smoka, podając jego imię i kolor

-- TODO: Wypisz kolejno:
-- 1. Imię pierwszego smoka
-- 2. Kolor pierwszego smoka
-- 3. Imię drugiego smoka
-- 4. Kolor drugiego smoka
-- 5. Żywioł pierwszego smoka (współdzielony przez klasę Dragon)
-- 6. Żywioł drugiego smoka (współdzielony przez klasę Dragon)
-- 7. Świat pierwszego smoka (współdzielony przez klasę Creature)
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