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 constructor'ının (yapıcısının), üst sınıfın başlatacağı her şeyin yanı sıra alt sınıfa özgü ek alanları da ilklendirmesini istersiniz. Kod tekrarı yapmak yerine, üst sınıfın constructor'ını doğrudan çağırabilirsiniz.

Bu teknik, üst sınıf adını kullanarak onun :new() metodunu çağırmayı ve ilk argüman olarak self değerini geçirmeyi içerir. Bu, tüm üst sınıf başlatmalarıyla birlikte temel nesneyi oluşturur ve ardından 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
end

Alt 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) çağrısını yaparız. Ardından, alt sınıfa özgü brand alanını ekleriz. Son olarak, örneğin (instance) metotları önce alt sınıfta araması için metatabloyu Vehicle yerine Car olarak değiştiririz.

Üst sınıf kurucusunu çağırırken iki nokta üst üste sözdizimini de kullanabilirsiniz — Vehicle:new(speed), her ikisi de ilk argüman olarak Vehicle değerini geçirdiği için Vehicle.new(Vehicle, speed) ile eşdeğerdir. Her iki form da burada doğru şekilde çalışır, bu nedenle hangisini daha okunabilir buluyorsanız onu kullanmaktan çekinmeyin.

local myCar = Car:new(120, "Toyota")
print(myCar.speed)  -- Çıktı: 120
print(myCar.brand)  -- Çıktı: Toyota

Bu desen kodunuzu DRY tutar; paylaşılan başlatma mantığı ebeveynde (parent) yer alırken, her bir çocuk (child) yalnızca kendi benzersiz özniteliklerini işler.

challenge icon

Görev

Kolay

Bir çocuk sınıfın ebeveyn sınıfının yapıcısını (constructor) genişlettiği bir yaratık 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 paylaşılan 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. __index ile standart sınıf desenini kurun ve sınıfı döndürün.
  • Bird.lua: Animal sınıfından miras alan çocuk sınıfınızı tanımlayın. Bird sınıfının :new(name, wingspan) yapıcısı, adı başlatmak için Animal.new(Animal, name) kullanarak ebeveyn yapıcısını çağırmalı, ardından nesneye wingspan alanı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:

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

Buradaki 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 miras zinciri oluştururken kodunuzu DRY (Don't Repeat Yourself) tutar!

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şturun

-- TODO: Kuş üzerinde :describe() metodunu çağırın (Animal sınıfından miras alınan)

-- TODO: Kuş üzerinde :info() metodunu çağırın (Bird sınıfında tanımlanan)
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