Menu
CoddyTech

Mixin'ler ve Kalıtım

Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 53 / 70.

Davranışları paylaşmanın iki yolunu öğrendin: kalıtım, prototip zinciri aracılığıyla bir "bir türüdür" ilişkisi oluştururken mixin'ler işlevleri doğrudan bir sınıfa kopyalar. Peki hangi yaklaşımı ne zaman kullanmalısın?

Nesneler temel bir kimliği paylaştığında kalıtımı kullan. Bir Bird, bir Animal'dır. Bird'ün :eat() veya :sleep() gibi temel hayvan davranışlarını devralması mantıklıdır. Bu ilişki kalıcıdır ve nesnenin özünde ne olduğunu tanımlar.

Nesnenin temel kimliğini tanımlamayan bir yetenek eklemek istediğinde mixins kullan.

Tüm kuşlar uçamaz: penguenler ve deve kuşları kuştur, ancak uçmazlar. Uçmak bir yetenektir; kuş olmanın tanımlayıcı bir özelliği değildir. Flyable mixin'i, uçma özelliğini tüm kuşlara zorunlu kılmadan, buna ihtiyaç duyan kuşlara eklemeni sağlar.

İki yaklaşım birlikte çalışır. Burada hem Eagle hem de Penguin, Bird sınıfından miras alır ve mixin'i yalnızca Eagle alır:

-- Bird, Animal sınıfından kalıtım alır (bir tür ilişkisidir)
local Bird = {}
Bird.__index = Bird
setmetatable(Bird, {__index = Animal})

-- Eagle ve Penguin, ikisi de kuştur
local Eagle = setmetatable({}, {__index = Bird})
Eagle.__index = Eagle
local Penguin = setmetatable({}, {__index = Bird})
Penguin.__index = Penguin

-- Flyable bir yetenektir (mixin)
local Flyable = {}
function Flyable:fly()
    print(self.name .. " soars through the sky!")
end

-- mixin'i yalnızca uçan kuşlara uygula
applyMixin(Eagle, Flyable)

Bir kartal :fly() çağırabilir. Bir penguen çağıramaz: fly, Penguin, Bird veya Animal içinde bulunmadığından penguin:fly() bir hatadır. Bunun yerine mixin'i Bird'e uygulamak, fly'ı penguenler de dahil olmak üzere tüm kuşlara kopyalardı.

challenge icon

Görev

Kolay

Hadi, kalıtımın mı yoksa mixin'lerin mi ne zaman kullanılacağını gösteren küçük bir canlı ekosistemi oluşturalım! Bir Animal temel sınıfı, ondan kalıtım alan bir Bird ve bir Swimmable mixin'i oluşturacaksın; çünkü tüm kuşlar hayvan olsa da tüm kuşlar yüzemez.

Kodunu dört dosyaya ayıracaksın:

  • Animal.lua: Adı saklayan :new(name) kurucusuna sahip temel Animal sınıfını oluştur. {name} is eating çıktısını veren bir :eat() yöntemi ekle. Bu, tüm hayvanların paylaştığı temel kimliği temsil eder.
  • Swimmable.lua: {self.name} is swimming çıktısını veren bir :swim() yöntemine sahip mixin oluştur. Bu bir yetenektir; tüm canlılar yüzemediğinden kalıtım zincirinin parçası olmamalıdır.
  • Bird.lua: Animal sınıfından kalıtım alan bir Bird sınıfı oluştur. :new(name) kurucusu üst sınıfın kurucusunu çağırmalıdır. {name} chirps! çıktısını veren bir :chirp() yöntemi ekle. Bu, kuşlara özgü bir davranıştır. Yüzme özelliğini Bird sınıfına ekleme: her kuş yüzemez.
  • main.lua: Mixin'in tüm işlevlerini hedefe kopyalayan applyMixin(target, mixin) yardımcı işlevini burada yaz. Kuşun adını ve yüzüp yüzemediğini (yes veya no) oku. Bir Bird oluştur ve yüzebiliyorsa Swimmable mixin'ini yalnızca o kuşa uygula. Ardından :eat() (Animal sınıfından kalıtılan) ve :chirp() (Bird sınıfının kendi yöntemi) yöntemlerini çağır; :swim() yöntemini ise yalnızca bu kuşta varsa çağır (if bird.swim then).

İki girdi alacaksın:

  1. Kuşun adı (bir metin)
  2. Kuşun yüzüp yüzemediği: yes veya no

Kuş yüzebiliyorsa çıktın şöyle olmalıdır:

{name} is eating
{name} chirps!
{name} is swimming

Kuş yüzemiyorsa çıktın şöyle olmalıdır:

{name} is eating
{name} chirps!

Örneğin, girdiler Duck ve yes ise çıktı şöyle olmalıdır:

Duck is eating
Duck chirps!
Duck is swimming

Girdiler Sparrow ve no ise çıktı şöyle olmalıdır:

Sparrow is eating
Sparrow chirps!

Bu alıştırma temel farkı gösterir: Bird bir Animal'dır (kalıtım), ancak yüzme isteğe bağlı bir yetenektir (mixin). Mixin yalnızca yüzebilen kuşlara eklendiği için yüzemeyen bir kuşta swim yöntemi hiç bulunmaz.

Kendin dene

-- main.lua: Giriş noktası - bir kuş oluştur ve yeteneklerini göster

-- Bir sınıfa veya tek bir nesneye mixin uygulamak için yardımcı fonksiyon
local function applyMixin(target, mixin)
    -- TODO: mixin içindeki tüm fonksiyonları target içine kopyala

end

local Bird = require('Bird')
local Swimmable = require('Swimmable')

-- Girdileri oku
local name = io.read()
local canSwimInput = io.read()

-- TODO: Verilen adla bir Bird örneği oluştur

-- TODO: Girdi "yes" ise Swimmable mixin öğesini yalnızca bu kuşa uygula

-- TODO: eat() fonksiyonunu çağır - Animal sınıfından miras alınmıştır

-- TODO: chirp() fonksiyonunu çağır - Bird sınıfının kendi metodu

-- TODO: swim() fonksiyonunu yalnızca bu kuşta varsa çağır
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Lua derleyicisi