Menu
Coddy logo textTech

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
end

Alt 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ı: Toyota

Bu 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.

challenge icon

Görev

Kolay

Bir 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. __index ile standart sınıf yapısını kur ve sınıfı döndür.
  • Bird.lua: Animal sınıfından miras alan alt sınıfını tanımla. Bird sınıfının :new(name, wingspan) yapıcısı, adı başlatmak için Animal.new(Animal, name) kullanarak üst sınıfın yapıcısını çağırmalı, ardından wingspan alanını nesneye eklemeli ve son olarak metatabloyu yeniden Bird sı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: Bird modülünü içe aktar, iki girdi (ad ve kanat açıklığı) oku, bir Bird ö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:

  1. Kuşun adı
  2. 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 200

Buradaki ö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ış)
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