Duck Typing
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 39 dari 70.
Lua tidak peduli dengan class suatu object. Lua hanya peduli dengan hal yang bisa dilakukan object tersebut. Konsep ini disebut duck typing: "Jika ia berjalan seperti bebek dan berkwek seperti bebek, berarti ia bebek." Dalam istilah pemrograman, jika suatu object memiliki method yang kamu panggil, method itu akan berfungsi.
Ini berarti class yang sama sekali tidak berkaitan dapat digunakan bersama, asalkan memiliki nama method yang sama:
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")
endclass-class ini tidak memiliki hubungan pewarisan: semuanya benar-benar independen. Namun, kita dapat memperlakukannya secara identik:
local shapes = {Circle:new(), Square:new(), Circle:new()}
for _, shape in ipairs(shapes) do
shape:draw()
end
-- Output:
-- Menggambar lingkaran
-- Menggambar persegi
-- Menggambar lingkaranPerulangan tidak memeriksa tipe setiap object. Perulangan hanya memanggil :draw() dan menganggap method itu ada. Fleksibilitas ini sangat berguna. Kamu bisa menambahkan tipe bentuk baru tanpa mengubah kode perulangan sama sekali. Selama class baru mengimplementasikan :draw(), semuanya langsung berfungsi.
Tantangan
MudahMari tunjukkan kehebatan duck typing dengan membuat sistem notifikasi menggunakan class yang sama sekali tidak berhubungan, tetapi semuanya dapat diproses dengan cara yang sama!
Kamu akan membuat tiga class notifikasi independen. Tidak ada yang mewarisi satu sama lain, tetapi semuanya mengimplementasikan method :send(). Artinya, kamu dapat melakukan perulangan melalui kumpulan campuran dan memanggil :send() pada setiap item tanpa perlu memedulikan tipe sebenarnya.
Kamu akan mengatur kodemu dalam empat file:
Email.lua: Class dengan constructor:new(recipient)yang menyimpan alamat tujuan email. Method:send()harus mencetakEmailing {recipient}.SMS.lua: Class terpisah sepenuhnya dengan constructor:new(phoneNumber). Method:send()harus mencetakTexting {phoneNumber}.PushNotification.lua: Class independen lainnya dengan constructor:new(deviceId). Method:send()harus mencetakPushing to {deviceId}.main.lua: Satukan semuanya! Baca tiga input, buat satu instance untuk setiap tipe notifikasi, masukkan semuanya ke dalam satu tabel, lalu lakukan perulangan dan panggil:send()pada setiap item.
Kamu akan menerima tiga input:
- Penerima email (misalnya,
alice@example.com) - Nomor telepon (misalnya,
555-1234) - ID perangkat (misalnya,
device_99)
Dalam file utama, buat ketiga object notifikasi, simpan semuanya dalam satu tabel, lalu iterasi melalui tabel sambil memanggil :send() pada setiap item. Urutannya harus: Email terlebih dahulu, lalu SMS, kemudian PushNotification.
Misalnya, jika inputnya adalah bob@mail.com, 555-9876, dan phone_42, outputnya harus:
Emailing bob@mail.com
Texting 555-9876
Pushing to phone_42Perhatikan bahwa perulanganmu tidak perlu memeriksa tipe setiap object. Perulangan itu hanya mengandalkan bahwa setiap object dalam kumpulan memiliki method :send(). Itulah duck typing dalam praktik! Jika object bisa menjalankan :send(), berarti object tersebut adalah notifikasi.
Coba sendiri
-- main.lua
-- Gabungkan semua jenis notifikasi dan tunjukkan duck typing
-- Impor semua class notifikasi
local Email = require('Email')
local SMS = require('SMS')
local PushNotification = require('PushNotification')
-- Baca input
local recipient = io.read()
local phoneNumber = io.read()
local deviceId = io.read()
-- TODO: Buat satu instance untuk setiap jenis notifikasi
-- TODO: Masukkan semua notifikasi ke dalam satu tabel (Email terlebih dahulu, lalu SMS, kemudian PushNotification)
-- TODO: Lakukan perulangan pada tabel dan panggil :send() pada setiap notifikasi
-- Ini menunjukkan duck typing: kita tidak memeriksa tipenya, cukup memanggil :send()
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Konsep "Self"
Tabel dengan Fungsi'self' EksplisitSintaks Titik DuaTitik vs Titik DuaRangkuman, Titik Bergerak4Proyek: Bank Digital
Penyiapan Proyekmethod Setoran7Polimorfisme & Overriding
Menimpa methodMemanggil method indukDuck TypingAntarmuka UmumMemeriksa TipeRingkasan: Peran Karyawan10Proyek: Pengelola Bentuk
Penyiapan Proyekclass Rectangleclass Circlemethod KelilingKumpulan BentukLuas TotalSaring Bentuk2Pola Prototype untuk class
Konsep PrototypeMenghubungkan dengan __indexKonstruktor :new()Menginisialisasi AtributInstans yang MandiriRangkuman: Pabrik Mobil5Pembebanan Operator dalam OOP
Menjumlahkan ObjekMengurangkan ObjekMenggabungkan ObjekMembandingkan Objek (<, >)Ulasan: Aritmetika Dompet8Enkapsulasi
Konvensi PenamaanClosure untuk PrivasiAkses melalui ClosureTabel Hanya-BacaLogika ValidasiRangkuman: Brankas Aman11Pola Desain (Ringan)
Fungsi FactoryTabel SingletonPola IteratorObserver (Listener)Rangkuman, Factory Logger3State dan Behavior pada object
Variabel InstansGetter methodSetter methodProperty TerhitungMemformat stringPemeriksaan KesetaraanRangkuman: Nilai Siswa6Dasar-Dasar Pewarisan
Menyiapkan PewarisanMewarisi methodMemperluas KonstruktorMenambahkan method untuk ChildSama vs UnikRangkuman: Hierarki BentukLatihan sendiri: Compiler Lua online