__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.
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 birRobotprototip tablosu tanımlayın:"RX-100"olarak ayarlanmış birmodelalanı100olarak ayarlanmış birbatteryLevelalanı- Robotun mevcut durumunu yazdıran bir
:status()metodu
main.lua: Robot modülünü içe aktarın (require), ardından boş bir örnek tablo oluşturun ve__indexilesetmetatablekullanarak 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:
- Girdi ismini örneğinizin
namealanına atayın (bu, örneğe özgü hale gelir) - Ö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
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