Duck Typing
Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 39 / 70.
Lua bir nesnenin sınıfını önemsemez. Yalnızca nesnenin ne yapabildiğiyle ilgilenir. Bu kavrama ördek tiplemesi denir: "Ördek gibi yürüyorsa ve ördek gibi vaklıyorsa, ördektir." Programlama terimleriyle, bir nesne çağırdığınız yönteme sahipse çalışır.
Bu, aynı yöntem adını 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 arasında 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 nesnenin hangi türde olduğunu kontrol etmez. Basitçe :draw() çağrısını yapar ve yöntemin mevcut 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() uyguladığı sürece sorunsuz çalışır.
Görev
KolayÖrdek yazımının gücünü, tamamen ilgisiz sınıflar kullanarak ve hepsini aynı şekilde işleyerek bir bildirim sistemi oluşturup gösterelim!
Birbirlerinden miras almayan, ancak her biri bir :send() yöntemi uygulayan üç bağımsız bildirim sınıfı oluşturacaksın. Bu, karışık bir koleksiyon üzerinde döngü kurup gerçek türünü önemsemeden her biri için :send() çağırabileceğin anlamına gelir.
Kodunu dört dosyaya ayıracaksın:
Email.lua: E-postanın kime gönderileceğini saklayan:new(recipient)yapıcısına sahip bir sınıf.:send()yöntemiEmailing {recipient}yazdırmalıdır.SMS.lua::new(phoneNumber)yapıcısına sahip, tamamen ayrı bir sınıf.:send()yöntemiTexting {phoneNumber}yazdırmalıdır.PushNotification.lua::new(deviceId)yapıcısına sahip başka bir bağımsız sınıf.:send()yöntemiPushing to {deviceId}yazdırmalıdır.main.lua: Her şeyi bir araya getir! Üç girdi oku, her bildirim türünden bir örnek oluştur, hepsini tek bir tabloya yerleştir, ardından tabloda döngü kurup her biri için:send()çağır.
Üç girdi alacaksın:
- Bir e-posta alıcısı (ör.
alice@example.com) - Bir telefon numarası (ör.
555-1234) - Bir cihaz kimliği (ör.
device_99)
Ana dosyanda üç bildirim nesnesinin tümünü oluştur, bunları bir tabloda sakla ve tabloda dolaşarak her biri için :send() çağır. Sıra şu şekilde olmalıdır: önce Email, ardından SMS, sonra PushNotification.
Örneğin girdiler bob@mail.com, 555-9876 ve phone_42 ise çıktı şöyle olmalıdır:
Emailing bob@mail.com
Texting 555-9876
Pushing to phone_42Döngünün her nesnenin hangi türde olduğunu kontrol etmesine gerek olmadığına dikkat et. Yalnızca koleksiyondaki her nesnenin bir :send() yöntemine sahip olduğuna güvenir. İşte ördek yazımı uygulamada böyle görünür! Eğer :send() yapabiliyorsa, bu bir bildirimdir.
Kendin dene
-- main.lua
-- Tüm bildirim türlerini bir araya getir ve duck typing'i göster
-- Bildirim sınıflarını içe aktar
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 bir örnek oluştur
-- TODO: Tüm bildirimleri tek bir tabloya koy (önce Email, sonra SMS, sonra PushNotification)
-- TODO: Tabloyu döngüyle gez ve her bildirim üzerinde :send() çağır
-- Bu duck typing'i gösterir - türü kontrol etmiyoruz, sadece :send() çağırıyoruz
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
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şisiKendi başına pratik yap: Online Lua derleyicisi