Menu
Coddy logo textTech

__index ile Bağlama

Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 7 / 70.

Özellikleri ve metotları olan bir prototip tablonuz var, ancak yeni bir nesnenin bunu gerçekten kullanmasını nasıl sağlarsınız? Cevap __index metametodunda yatmaktadır.

Bir tabloda var olmayan bir anahtara eriştiğinizde, Lua normalde nil döndürür. Ancak, tablonun __index alanına sahip bir metatablosu varsa, Lua bunun yerine oraya bakacaktır. __index alanını prototipinize işaret edecek şekilde ayarlayarak, eksik olan tüm anahtarlar otomatik olarak prototipte bulunur:

local Dog = {
    species = "Canis familiaris",
    legs = 4
}

function Dog:bark()
    print("Woof!")
end

-- Boş bir örnek oluşturun
local myDog = {}

-- Onu prototipe bağlayın
setmetatable(myDog, { __index = Dog })

print(myDog.species)  -- Çıktı: Canis familiaris
myDog:bark()          -- Çıktı: Woof!

myDog tablosu tamamen boştur, ancak myDog.species erişimi çalışır. Lua, myDog içinde species bulamadığında, metatablo'nun __index kısmını kontrol eder ve onu Dog içinde bulur.

Bu, Lua'da nesne yönelimli programlamanın temelidir. Örnek (instance) kendi benzersiz verilerine sahip olabilirken, paylaşılan davranış prototipte yer alır. Bir sonraki derste, bu deseni temiz bir yapıcı (constructor) fonksiyonuna nasıl sarmalayacağınızı öğreneceksiniz.

challenge icon

Görev

Kolay

Şimdi __index metametodunu uygulamaya koyalım! Bir prototip oluşturacak ve bir örneği (instance) ona bağlayacaksınız; bu, örneğin doğrudan sahip olmadığı özelliklere ve metotlara erişmesine olanak tanıyacaktır.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • Robot.lua: Aşağıdakileri içeren bir Robot prototip tablosu tanımlayın:
    • "RX-100" olarak ayarlanmış bir model alanı
    • 100 olarak ayarlanmış bir batteryLevel alanı
    • Robotun mevcut durumunu yazdıran bir :status() metodu
    Dosyanın sonunda tabloyu döndürün.
  • main.lua: Robot modülünü içe aktarın (require), ardından boş bir örnek tablo oluşturun ve __index ile setmetatable kullanarak bunu Robot prototipine bağlayın. Bu, boş örneğinizin prototipteki her şeye erişmesini sağlar.

Bir girdi alacaksınız: robot örneğinize atanacak bir isim.

Örneği prototipe bağladıktan sonra:

  1. Girdi ismini örneğinizin name alanına atayın (bu, örneğe özgü hale gelir)
  2. Örneğiniz üzerinde :status() metodunu çağırın

:status() metodunuz tam olarak şu formatta yazdırmalıdır:

[name] ([model]) - Battery: [batteryLevel]%

Örneğin, girdi Sparky ise, çıktı şu olmalıdır:

Sparky (RX-100) - Battery: 100%

Örneği kendi name alanına sahip olduğuna, ancak model ve batteryLevel değerlerine __index bağlantısı aracılığıyla prototipten nasıl eriştiğine dikkat edin.

Kopya kağıdı

__index metametodu, nesnelerin bir prototip tablodan özellikler ve metotlar miras almasını sağlar.

Bir tabloda var olmayan bir anahtara eriştiğinizde, Lua tablonun __index alanına sahip bir metatablosu olup olmadığını kontrol eder. Eğer varsa, Lua anahtarı __index tarafından belirtilen tabloda arar.

Bir örneği (instance) bir prototipe bağlamak için:

local Prototype = {
    property = "value"
}

function Prototype:method()
    print("Method called")
end

-- Bir örnek oluştur
local instance = {}

-- __index kullanarak prototipe bağla
setmetatable(instance, { __index = Prototype })

-- Prototip özelliklerine ve metotlarına eriş
print(instance.property)  -- Çıktı: value
instance:method()         -- Çıktı: Method called

Örnek tablosu boş olabilir, ancak yine de prototipteki tüm özelliklere ve metotlara erişebilir. Örnek, prototipi geçersiz kılan veya genişleten kendine özgü özelliklere de sahip olabilir.

Bu desen, örneklerin kendi benzersiz verilerini korurken bir prototipten davranış paylaştığı Lua'daki nesne yönelimli programlamanın temelidir.

Kendin dene

-- Girdiyi oku
local name = io.read()

-- Robot modülünü dahil et
local Robot = require('Robot')

-- YAPILACAK: Boş bir örnek (instance) tablosu oluşturun

-- YAPILACAK: __index ile setmetatable kullanarak örneği Robot prototipine bağlayın

-- YAPILACAK: Girdi ismini örneğinizin name alanına atayın

-- YAPILACAK: Örneğiniz üzerinde :status() metodunu çağırın
quiz iconKendini test et

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