Duck Typing
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 39 / 70.
Lua bir nesnenin sınıfını umursamaz; yalnızca nesnenin neler yapabildiğiyle ilgilenir. Bu kavram duck typing (ördek tiplemesi) olarak adlandırılır: "Eğer bir ördek gibi yürüyor ve bir ördek gibi vakvaklıyorsa, o bir ördektir." Programlama terimleriyle ifade etmek gerekirse, eğer bir nesne çağırdığınız metoda sahipse, çalışır.
Bu, aynı metot ismini paylaştıkları sürece tamamen ilgisiz sınıfların birlikte kullanılabileceği anlamına gelir:
local Circle = {}
Circle.__index = Circle
function Circle:new()
local obj = {}
setmetatable(obj, Circle)
return obj
end
function Circle:draw()
print("Drawing a circle")
end
local Square = {}
Square.__index = Square
function Square:new()
local obj = {}
setmetatable(obj, Square)
return obj
end
function Square:draw()
print("Drawing a square")
endBu sınıfların hiçbir kalıtım ilişkisi yoktur; tamamen bağımsızdırlar. Yine de onlara aynı şekilde davranabiliriz:
local shapes = {Circle:new(), Square:new(), Circle:new()}
for _, shape in ipairs(shapes) do
shape:draw()
end
-- Çıktı:
-- Bir daire çiziliyor
-- Bir kare çiziliyor
-- Bir daire çiziliyorDöngü, her bir nesnenin hangi türde olduğunu kontrol etmez. Sadece :draw() metodunu çağırır ve metodun var olduğuna güvenir. Bu esneklik güçlüdür; döngü kodunu hiç değiştirmeden yeni şekil türleri ekleyebilirsiniz. Yeni sınıf :draw() metodunu uyguladığı sürece, sorunsuz çalışır.
Görev
KolayHepsi aynı şekilde işlenebilen, tamamen ilgisiz sınıflarla bir bildirim sistemi oluşturarak duck typing'in gücünü gösterelim!
Üç bağımsız bildirim sınıfı oluşturacaksınız—hiçbiri birbirinden miras almaz—ancak hepsi bir :send() metodu uygular. Bu, karışık bir koleksiyon içinde döngü kurabileceğiniz ve gerçek türünü önemsemeden her biri üzerinde :send() metodunu çağırabileceğiniz anlamına gelir.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Email.lua: E-postanın kime gideceğini saklayan bir:new(recipient)kurucusuna sahip bir sınıf.:send()metoduEmailing {recipient}yazdırmalıdır.SMS.lua::new(phoneNumber)kurucusuna sahip tamamen ayrı bir sınıf.:send()metoduTexting {phoneNumber}yazdırmalıdır.PushNotification.lua::new(deviceId)kurucusuna sahip başka bir bağımsız sınıf.:send()metoduPushing to {deviceId}yazdırmalıdır.main.lua: Her şeyi bir araya getirin! Üç girdi okuyun, her bildirim türünden birer örnek oluşturun, hepsini tek bir tabloya koyun, ardından tabloyu döngüye sokun ve her biri üzerinde:send()metodunu çağırın.
Üç girdi alacaksınız:
- Bir e-posta alıcısı (örneğin,
alice@example.com) - Bir telefon numarası (örneğin,
555-1234) - Bir cihaz kimliği (örneğin,
device_99)
Ana dosyanızda, her üç bildirim nesnesini de oluşturun, bunları bir tabloda saklayın ve tablo üzerinde gezinerek her biri için :send() metodunu çağırın. Sıralama şu şekilde olmalıdır: Önce Email, sonra SMS, ardından PushNotification.
Örneğin, girdiler bob@mail.com, 555-9876 ve phone_42 ise, çıktı şu şekilde olmalıdır:
Emailing bob@mail.com
Texting 555-9876
Pushing to phone_42Döngünüzün her nesnenin hangi türde olduğunu kontrol etmesine gerek kalmadığına dikkat edin—sadece koleksiyondaki her nesnenin bir :send() metoduna sahip olduğuna güvenir. İşte bu, iş başındaki duck typing'dir! Eğer :send() yapabiliyorsa, o bir bildirimdir.
Kopya kağıdı
Lua duck typing (ördek tiplemesi) kullanır: Eğer bir nesne çağırdığınız metoda sahipse, sınıfı ne olursa olsun çalışır. İlke şudur: "Eğer bir ördek gibi yürüyorsa ve bir ördek gibi vakvaklıyorsa, o bir ördektir."
Tamamen ilgisiz sınıflar, aynı metod ismini paylaştıkları sürece birbirlerinin yerine kullanılabilirler:
local Circle = {}
Circle.__index = Circle
function Circle:new()
local obj = {}
setmetatable(obj, Circle)
return obj
end
function Circle:draw()
print("Drawing a circle")
end
local Square = {}
Square.__index = Square
function Square:new()
local obj = {}
setmetatable(obj, Square)
return obj
end
function Square:draw()
print("Drawing a square")
endBu sınıfların aralarında bir kalıtım ilişkisi yoktur, ancak yine de aynı şekilde ele alınabilirler:
local shapes = {Circle:new(), Square:new(), Circle:new()}
for _, shape in ipairs(shapes) do
shape:draw()
end
-- Çıktı:
-- Drawing a circle
-- Drawing a square
-- Drawing a circleDöngü nesne türlerini kontrol etmez; sadece metodu çağırır ve var olduğuna güvenir. Gerekli metodu uyguladıkları sürece, mevcut kodu değiştirmeden yeni türler ekleyebilirsiniz.
Kendin dene
-- main.lua
-- Tüm bildirim türlerini bir araya getirin ve duck typing (ördek tipleme) yöntemini gösterin
-- Bildirim sınıflarını içe aktarın
local Email = require('Email')
local SMS = require('SMS')
local PushNotification = require('PushNotification')
-- Girdileri oku
local recipient = io.read()
local phoneNumber = io.read()
local deviceId = io.read()
-- TODO: Her bildirim türünden birer örnek oluşturun
-- TODO: Tüm bildirimleri tek bir tabloya koyun (Önce Email, sonra SMS, sonra PushNotification)
-- TODO: Tablo üzerinde döngü kurun ve her bildirim için :send() metodunu çağırın
-- Bu, duck typing'i gösterir - türü kontrol etmeyiz, sadece :send() metodunu çağırırız
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