Constructor'ı Genişletme
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 33 / 70.
Bir alt sınıf bir üst sınıftan miras aldığında, genellikle alt sınıfın yapıcısının (constructor), üst sınıfın yapacağı her şeyi ve buna ek olarak alt sınıfa özgü tüm ek alanları başlatmasını istersiniz. Kodu çoğaltmak yerine, üst sınıfın yapıcısını doğrudan çağırabilirsiniz.
Bu teknik, üst sınıf adını kullanarak onun :new() metodunu çağırmayı ve ilk argüman olarak üst sınıfı geçmeyi içerir. Bunu nokta sözdizimi ile yapabilirsiniz: Vehicle.new(Vehicle, speed) veya eşdeğer olarak iki nokta üst üste sözdizimi ile: Vehicle:new(speed) — her ikisi de geçerlidir ve aynı sonucu verir. Bu, tüm üst sınıf başlatmalarıyla birlikte temel nesneyi oluşturur ve daha sonra bunu alt sınıf için özelleştirirsiniz.
local Vehicle = {}
Vehicle.__index = Vehicle
function Vehicle:new(speed)
local obj = {speed = speed}
setmetatable(obj, Vehicle)
return obj
end
-- Car, Vehicle'dan miras alır
local Car = {}
Car.__index = Car
setmetatable(Car, {__index = Vehicle})
function Car:new(speed, brand)
local obj = Vehicle.new(Vehicle, speed) -- Üst sınıf kurucusunu çağır
obj.brand = brand -- Alt sınıfa özgü alan ekle
setmetatable(obj, Car) -- Car'a yeniden bağla
return obj
endAlt sınıf yapıcı metodundaki (child constructor) temel adımlara dikkat edin: İlk olarak, speed alanı halihazırda ayarlanmış bir nesne elde etmek için Vehicle.new(Vehicle, speed) (veya eşdeğeri olan Vehicle:new(speed)) çağrısını yapıyoruz. Ardından, alt sınıfa özgü brand alanını ekliyoruz. Son olarak, örneğin (instance) metodları ilk olarak alt sınıfta araması için metatabloyu Vehicle yerine Car olarak değiştiriyoruz.
local myCar = Car:new(120, "Toyota")
print(myCar.speed) -- Çıktı: 120
print(myCar.brand) -- Çıktı: ToyotaBu desen kodunuzun DRY kalmasını sağlar; paylaşılan başlatma mantığı ebeveynde yer alırken, her bir çocuk yalnızca kendine özgü niteliklerini işler.
Görev
KolayBir çocuk sınıfın ebeveyn sınıfının yapıcısını (constructor) genişlettiği bir canlı hiyerarşisi oluşturalım! Bir Animal ebeveyn sınıfı ve bir Bird çocuk sınıfı oluşturacaksınız; burada Bird'ün yapıcısı, kendi benzersiz özniteliğini eklemeden önce ortak başlatma işlemlerini yönetmek için Animal'ın yapıcısını çağıracak.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
Animal.lua: Hayvanın adını saklayan bir:new(name)yapıcısı ile ebeveyn sınıfınızı tanımlayın. Hayvanın adını yazdıran bir:describe()metodu ekleyin.__indexile standart sınıf desenini kurun ve sınıfı döndürün.Bird.lua: Animal'dan miras alan çocuk sınıfınızı tanımlayın. Bird'ün:new(name, wingspan)yapıcısı, adı başlatmak içinAnimal.new(Animal, name)kullanarak ebeveyn yapıcıyı çağırmalı, ardından nesneyewingspanalanını eklemeli ve son olarak metatabloyu tekrar Bird'e bağlamalıdır. Hem adı hem de kanat açıklığını belirli bir formatta yazdıran bir:info()metodu ekleyin.main.lua: Bird modülünüzü dahil edin (require), iki girdi (ad ve kanat açıklığı) okuyun, bir Bird örneği oluşturun ve miras alınan ve çocuğa özgü işlevlerin birlikte çalıştığını göstermek için her iki metodu da çağırın.
İki girdi alacaksınız:
- Kuşun adı
- Kuşun kanat açıklığı (bir sayı)
Ana dosyanızda, verilen ad ve kanat açıklığı ile bir Bird oluşturun. Ardından ayrı satırlarda önce :describe(), sonra :info() metodunu çağırın.
:describe() metodu (Animal'dan miras alınan) şunu yazdırmalıdır:
Animal: {name}:info() metodu (Bird içinde tanımlanan) şunu yazdırmalıdır:
{name} has a wingspan of {wingspan}Örneğin, girdiler Eagle ve 200 ise, çıktı şöyle olmalıdır:
Animal: Eagle
Eagle has a wingspan of 200Buradaki kilit nokta, Bird yapıcınızın ad başlatma işlemini tekrarlamamasıdır; bu işi Animal'ın yapıcısına devreder ve ardından yalnızca kuşlara özgü olanı ekler. Bu, uygun bir kalıtım zinciri oluştururken kodunuzu DRY (Don't Repeat Yourself) prensibine uygun tutar!
Kopya kağıdı
Bir alt sınıftan üst sınıf (parent class) yapıcısını (constructor) çağırmak için, üst sınıf adını nokta sözdizimiyle kullanın ve ilk argüman olarak üst sınıfın kendisini geçirin:
local obj = ParentClass.new(ParentClass, parentArgs)Üst sınıf yapıcısını çağırdıktan sonra, alt sınıfa özgü alanları ekleyin ve metatabloyu alt sınıfa yeniden bağlayın:
local Vehicle = {}
Vehicle.__index = Vehicle
function Vehicle:new(speed)
local obj = {speed = speed}
setmetatable(obj, Vehicle)
return obj
end
local Car = {}
Car.__index = Car
setmetatable(Car, {__index = Vehicle})
function Car:new(speed, brand)
local obj = Vehicle.new(Vehicle, speed) -- Üst sınıf yapıcısını çağır
obj.brand = brand -- Alt sınıfa özgü alan ekle
setmetatable(obj, Car) -- Car sınıfına yeniden bağla
return obj
end
local myCar = Car:new(120, "Toyota")
print(myCar.speed) -- Çıktı: 120
print(myCar.brand) -- Çıktı: ToyotaBu desen, başlatma (initialization) mantığını DRY (Don't Repeat Yourself) tutar; ortak kurulum üst sınıfta yer alırken, alt sınıflar yalnızca kendilerine özgü nitelikleri yönetir.
Kendin dene
-- main.lua: Giriş noktası
local Bird = require('Bird')
-- Girdileri oku
local name = io.read()
local wingspan = tonumber(io.read())
-- TODO: Verilen isim ve kanat açıklığı ile bir Bird örneği oluşturun
-- TODO: Kuş üzerinde :describe() metodunu çağırın (Animal'dan miras alınmıştır)
-- TODO: Kuş üzerinde :info() metodunu çağırın (Bird içinde tanımlanmıştır)
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şisi