Menu
Coddy logo textTech

Właściwości obliczane

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

Gettery i settery zapewniają dostęp do przechowywanych wartości, ale czasami potrzebujesz danych, które nie istnieją jako przechowywane pole. Trzeba je obliczyć na podstawie innych atrybutów. Nazywa się je właściwościami obliczanymi.

Rozważ prostokąt. Zapisujesz jego szerokość i wysokość, ale pole nie jest nigdzie przechowywane: oblicza się je, mnożąc te dwie wartości. Zamiast przechowywać nadmiarowe dane, tworzysz metodę, która oblicza i zwraca wynik:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

Metoda :getArea() nie zwraca zapisanej wartości. Oblicza pole od nowa za każdym razem, gdy ją wywołujesz. To podejście ma istotną zaletę: jeśli szerokość lub wysokość się zmieni, pole automatycznie uwzględni nowe wymiary, bez konieczności aktualizowania czegokolwiek.

local box = Rectangle:new(5, 3)
print(box:getArea())  -- Wynik: 15

box.width = 10
print(box:getArea())  -- Wynik: 30

Właściwości obliczane pomagają zachować spójność obiektów. Zamiast przechowywać wartości zależne od innych pól (i ryzykować, że staną się nieaktualne), obliczasz je na żądanie. Ten wzorzec sprawdza się w przypadku wszelkich danych pochodnych: obwodów, średnich, sformatowanych ciągów znaków lub dowolnej wartości, którą można wyznaczyć na podstawie istniejących atrybutów.

challenge icon

Wyzwanie

Łatwy

Zbudujmy klasę Box, która oblicza swoją objętość na żądanie! Zamiast przechowywać objętość jako pole, utworzysz obliczaną właściwość, która wylicza ją z wymiarów pudełka zawsze wtedy, gdy jest potrzebna.

Rozmieścisz swój kod w dwóch plikach:

  • Box.lua: Zdefiniuj klasę Box przy użyciu standardowego wzorca prototypowego. Każde pudełko przechowuje trzy wymiary: width, height i depth. Uwzględnij:
    • Konstruktor :new(width, height, depth), który przechowuje wszystkie trzy wymiary
    • Metodę :getVolume(), która oblicza i zwraca objętość (width × height × depth)
    • Metodę :getSurfaceArea(), która oblicza i zwraca całkowite pole powierzchni
  • main.lua: Załaduj swój moduł Box, utwórz instancję pudełka i pokaż, jak obliczane właściwości automatycznie uwzględniają aktualne wymiary.

Pole powierzchni pudełka oblicza się następująco: 2 × (width×height + height×depth + width×depth)

Otrzymasz trzy dane wejściowe reprezentujące wymiary pudełka:

  1. Szerokość
  2. Wysokość
  3. Głębokość

W pliku głównym utwórz pudełko o podanych wymiarach, a następnie wypisz dwa wiersze:

  1. Objętość za pomocą :getVolume()
  2. Pole powierzchni za pomocą :getSurfaceArea()

Na przykład, jeśli dane wejściowe to 3, 4 i 5, wynik powinien wyglądać tak:

60
94

Zaletą obliczanych właściwości jest to, że zawsze pozostają aktualne. Jeśli później zmienisz jeden z wymiarów pudełka, ponowne wywołanie :getVolume() automatycznie zwróci prawidłową nową wartość: nie trzeba niczego aktualizować ręcznie!

Spróbuj swoich sił

-- Załaduj moduł Box za pomocą require
local Box = require('Box')

-- Odczytaj wymiary wejściowe
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())

-- TODO: Utwórz instancję pudełka o podanych wymiarach

-- TODO: Wypisz objętość za pomocą :getVolume()

-- TODO: Wypisz pole powierzchni za pomocą :getSurfaceArea()
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