Mixin'ler ve Kalıtım
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 53 / 70.
Davranış paylaşmanın iki yolunu öğrendiniz: kalıtım prototip zinciri aracılığıyla bir "is-a" ilişkisi oluştururken, mixin'ler fonksiyonları doğrudan bir sınıfa kopyalar. Peki, her bir yaklaşımı ne zaman kullanmalısınız?
Nesneler temel bir kimliği paylaştığında kalıtım kullanın. Bir Bird bir Animal'dır—Bird'ün :eat() veya :sleep() gibi temel hayvan davranışlarını miras alması mantıklıdır. Bu ilişki kalıcıdır ve nesnenin temel olarak ne olduğunu tanımlar.
Nesnenin temel kimliğini tanımlamayan bir yetenek eklemek istediğinizde mixin'leri kullanın.
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. Bir Flyable mixin'i, tüm kuşlara zorunlu kılmadan, ihtiyacı olan kuşlara uçma yeteneği eklemenizi sağlar.
Bu iki yaklaşım birlikte mükemmel bir şekilde çalışır:
-- Bird, Animal'dan miras alır (is-a ilişkisi)
local Bird = {}
Bird.__index = Bird
setmetatable(Bird, {__index = Animal})
-- Flyable bir yetenektir (mixin)
local Flyable = {}
function Flyable:fly()
print(self.name .. " soars through the sky!")
end
-- Mixin'i sadece uçabilen kuşlara uygula
applyMixin(Bird, Flyable)Bu desen size her iki dünyanın da en iyisini sunar: ortak kimlik için net bir sınıf hiyerarşisi ve ihtiyaç duyulan yerlerde eklenebilen esnek yetenekler.
Görev
KolayKalıtım (inheritance) ile mixin'lerin ne zaman kullanılacağını gösteren küçük bir canlı ekosistemi inşa edelim! Bir Animal temel sınıfı, ondan kalıtım alan bir Bird sınıfı ve bir Swimmable mixin'i oluşturacaksınız; çünkü tüm kuşlar hayvandır, ancak tüm kuşlar yüzemez.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Animal.lua: İsmi saklayan bir:new(name)yapıcı metoduna (constructor) sahip temel Animal sınıfını oluşturun.{name} is eatingçıktısını veren bir:eat()metodu ekleyin. Bu, tüm hayvanların paylaştığı temel kimliği temsil eder.Swimmable.lua:{self.name} is swimmingçıktısını veren bir:swim()metoduna sahip bir mixin oluşturun. Bu bir yetenektir; tüm canlılar yüzemez, bu yüzden kalıtım zincirinin bir parçası olmamalıdır.Bird.lua: Animal sınıfından kalıtım alan bir Bird sınıfı oluşturun.:new(name, canSwim)yapıcı metodu, üst sınıfın yapıcı metodunu çağırmalı ve bu kuşun yüzüp yüzemeyeceğini saklamalıdır. Swimmable mixin'ini Bird sınıfına uygulayın.{name} chirps!çıktısını veren bir:chirp()metodu ekleyin; bu, kuşa özgü bir davranıştır.main.lua:applyMixinyardımcı fonksiyonunu burada yazın. Bir kuşun adı ve yüzüp yüzemediği (yesveyano) için girdileri okuyun. Bir Bird örneği oluşturun, ardından yeteneklerini sergileyin::eat()(Animal'dan kalıtım alınan),:chirp()(Bird'ün kendi metodu) metodlarını çağırın ve yalnızca kuş yüzebiliyorsa:swim()metodunu çağırın.
İki girdi alacaksınız:
- Kuşun adı (bir dize)
- Kuşun yüzüp yüzemediği:
yesveyano
Eğer kuş yüzebiliyorsa, çıktınız şu şekilde olmalıdır:
{name} is eating
{name} chirps!
{name} is swimmingEğer kuş yüzemiyorsa, çıktınız şu şekilde olmalıdır:
{name} is eating
{name} chirps!Örneğin, girdiler Duck ve yes ise, çıktı şu şekilde olmalıdır:
Duck is eating
Duck chirps!
Duck is swimmingGirdiler Sparrow ve no ise, çıktı şu şekilde olmalıdır:
Sparrow is eating
Sparrow chirps!Bu zorluk temel ayrımı göstermektedir: Bird bir Animal'dır (kalıtım), ancak yüzme isteğe bağlı bir yetenektir (mixin). Mixin sınıfa uygulanır, ancak ana mantığınız bunu bireysel kuşun yeteneklerine göre kullanıp kullanmamaya karar verir!
Kopya kağıdı
Nesneler temel bir kimliği paylaştığında (bir "is-a" ilişkisi) kalıtım kullanın. Nesnenin temel kimliğini tanımlamayan yetenekler eklerken mixin'ler kullanın.
Kalıtım, prototip zinciri aracılığıyla kalıcı bir ilişki oluşturur:
local Bird = {}
Bird.__index = Bird
setmetatable(Bird, {__index = Animal})Mixin'ler, seçici olarak uygulanabilen isteğe bağlı yetenekler ekler:
local Flyable = {}
function Flyable:fly()
print(self.name .. " soars through the sky!")
end
applyMixin(Bird, Flyable)İki yaklaşım birlikte çalışır: paylaşılan kimlik için kalıtımı, yalnızca bazı örneklerin ihtiyaç duyduğu esnek yetenekler için ise mixin'leri kullanın.
Kendin dene
-- main.lua: Giriş noktası - bir kuş oluşturun ve yeteneklerini gösterin
-- Bir sınıfa mixin uygulamak için yardımcı fonksiyon
local function applyMixin(class, mixin)
-- TODO: Mixin'deki tüm metotları sınıfa kopyalayın
end
-- Bird'ü require etmeden önce Swimmable mixin'ini Bird'e uygulayın
-- Not: Bunu Bird.lua içinde veya burada halletmeniz gerekebilir
local Bird = require('Bird')
local Swimmable = require('Swimmable')
-- Mixin'i Bird sınıfına uygula
applyMixin(Bird, Swimmable)
-- Girdileri oku
local name = io.read()
local canSwimInput = io.read()
-- TODO: Girdiye göre kuşun yüzüp yüzemeyeceğini belirleyin ("yes" veya "no")
-- TODO: İsim ve yüzme yeteneği ile bir Bird örneği oluşturun
-- TODO: eat() metodunu çağırın - Animal sınıfından miras alınmıştır
-- TODO: chirp() metodunu çağırın - Bird sınıfının kendi metodu
-- TODO: swim() metodunu sadece kuş yüzebiliyorsa çağırın
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1'Self' Kavramı
Fonksiyonlu TablolarAçık 'self'İki Nokta SözdizimiNokta vs İki NoktaÖzet - Hareket Eden Nokta4Proje: Dijital Banka
Proje KurulumuPara Yatırma Metodu7Çok Biçimlilik ve Geçersiz Kılma
Metotları Geçersiz KılmaÜst Sınıf Metotlarını ÇağırmaDuck TypingOrtak ArayüzTür KontrolüÖzet - Çalışan Rolleri2Sınıf Prototip Kalıbı
Prototip Kavramı__index ile Bağlama:new() KurucusuÖznitelikleri BaşlatmaBağımsız ÖrneklerÖzet - Araba Fabrikası5OOP'de Operatör Aşırı Yükleme
Nesneleri ToplamaNesneleri ÇıkarmaNesneleri BirleştirmeNesneleri Karşılaştırma (<, >)Özet - Cüzdan Matematiği8Kapsülleme
Adlandırma KurallarıGizlilik için Closure'larClosure'lar Aracılığıyla ErişimSalt Okunur TablolarDoğrulama MantığıÖzet - Güvenli Kasa11Tasarım Kalıpları (Lite)
Fabrika FonksiyonlarıSingleton TablosuIterator KalıbıObserver (Dinleyici)Özet - Logger Fabrikası3Nesne Durumu ve Davranışı
Örnek DeğişkenleriGetter MetotlarıSetter MetotlarıHesaplanmış ÖzelliklerString BiçimlendirmeEşitlik KontrolleriÖzet - Öğrenci Notu6Kalıtımın Temelleri
Kalıtım KurulumuMetot KalıtımıConstructor'ı GenişletmeAlt Sınıf Metotları EklemePaylaşılan ve BenzersizÖzet - Şekil Hiyerarşisi9Kompozisyon ve Mixin'ler
Has-A İlişkisiDelegasyonBasit Mixin'lerBirden Fazla Mixin UygulamaMixin'ler ve KalıtımÖzet - Robot Birleştirme