Constructor'ı Genişletme
Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama 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 kurucusunun üst sınıfın başlatacağı her şeyi ve alt sınıfa özgü ek alanları başlatmasını istersiniz. Kodu tekrarlamak yerine, üst sınıfın kurucusunu doğrudan çağırabilirsiniz.
Teknik, :new() yöntemini çağırmak için üst sınıf adının kullanılmasını ve ilk bağımsız değişken olarak self değerinin geçirilmesini içerir. Bu, tüm üst sınıf başlatma işlemleriyle temel nesneyi oluşturur; ardından bu nesneyi 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 yapıcısını ç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 oluşturucusundaki temel adımlara dikkat edin: önce, speed alanı zaten ayarlanmış bir nesne elde etmek için Vehicle.new(Vehicle, speed) çağrısını yaparız. Ardından alt sınıfa özgü brand alanını ekleriz. Son olarak, örneğin yöntemleri önce alt sınıfta araması için metatabloyu Vehicle değerinden Car değerine değiştiririz.
Üst sınıf oluşturucusunu çağırırken iki nokta üst üste söz dizimini de kullanabilirsiniz: Vehicle:new(speed), her ikisi de ilk bağımsız değişken olarak Vehicle değerini geçirdiği için Vehicle.new(Vehicle, speed) ile eşdeğerdir. Burada her iki biçim de doğru şekilde çalışır; bu nedenle daha okunabilir bulduğunuz biçimi kullanabilirsiniz.
local myCar = Car:new(120, "Toyota")
print(myCar.speed) -- Çıktı: 120
print(myCar.brand) -- Çıktı: ToyotaBu kalıp kodunuzu DRY tutar: ortak başlatma mantığı üst sınıfta yer alırken her alt sınıf yalnızca kendine özgü öznitelikleri ele alır.
Görev
KolayBir alt sınıfın üst sınıfının yapıcısını genişlettiği bir canlı hiyerarşisi oluşturalım! Bir Animal üst sınıfı ve Bird alt sınıfı oluşturacaksın; Bird sınıfının yapıcısı, kendi benzersiz özelliğini eklemeden önce ortak başlatmayı gerçekleştirmek için Animal sınıfının yapıcısını çağıracak.
Kodunu üç dosya arasında düzenleyeceksin:
Animal.lua: Hayvanın adını saklayan bir:new(name)yapıcısıyla üst sınıfını tanımla. Hayvanın adını yazdıran bir:describe()yöntemi ekle.__indexile standart sınıf yapısını kur ve sınıfı döndür.Bird.lua:Animalsınıfından miras alan alt sınıfını tanımla.Birdsınıfının:new(name, wingspan)yapıcısı, adı başlatmak içinAnimal.new(Animal, name)kullanarak üst sınıfın yapıcısını çağırmalı, ardındanwingspanalanını nesneye eklemeli ve son olarak metatabloyu yenidenBirdsınıfına bağlamalıdır. Hem adı hem de kanat açıklığını belirli bir biçimde yazdıran bir:info()yöntemi ekle.main.lua:Birdmodülünü içe aktar, iki girdi (ad ve kanat açıklığı) oku, birBirdörneği oluştur ve miras alınan işlevlerle alt sınıfa özgü işlevlerin birlikte çalıştığını göstermek için her iki yöntemi çağır.
İki girdi alacaksın:
- Kuşun adı
- Kuşun kanat açıklığı (bir sayı)
ana dosyanda, verilen ad ve kanat açıklığıyla bir Bird oluştur. Ardından ayrı satırlarda :describe() ve sonra :info() yöntemini çağır.
:describe() yöntemi (Animal sınıfından miras alınmıştır) şunu yazdırmalı:
Animal: {name}:info() yöntemi (Bird sınıfında tanımlanmıştır) şunu yazdırmalı:
{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 önemli nokta, Bird yapıcısının ad başlatma işlemini tekrarlamamasıdır. Bu işi Animal sınıfının yapıcısına devreder, ardından yalnızca kuşlara özgü olanı ekler. Böylece düzgün bir kalıtım zinciri oluştururken kodunu DRY tutarsın!
Kendin dene
-- main.lua: Giriş noktası
local Bird = require('Bird')
-- Girdileri oku
local name = io.read()
local wingspan = tonumber(io.read())
-- TODO: Verilen name ve wingspan ile bir Bird örneği oluştur
-- TODO: bird üzerinde :describe() çağır (Animal'dan miras alınan)
-- TODO: bird üzerinde :info() çağır (Bird'de tanımlanmış)
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
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şisiKendi başına pratik yap: Online Lua derleyicisi