Memperluas Konstruktor
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 33 dari 70.
Saat sebuah class anak mewarisi dari class induk, kamu sering ingin konstruktor class anak menginisialisasi semua hal yang akan diinisialisasi oleh class induk, ditambah field tambahan yang khusus untuk class anak. Daripada menduplikasi kode, kamu bisa langsung memanggil konstruktor class induk.
Teknik ini menggunakan nama class induk untuk memanggil method :new(), dengan meneruskan self sebagai argumen pertama. Ini membuat object dasar dengan semua inisialisasi dari induk, lalu kamu menyesuaikannya untuk child.
local Vehicle = {}
Vehicle.__index = Vehicle
function Vehicle:new(speed)
local obj = {speed = speed}
setmetatable(obj, Vehicle)
return obj
end
-- Car mewarisi Vehicle
local Car = {}
Car.__index = Car
setmetatable(Car, {__index = Vehicle})
function Car:new(speed, brand)
local obj = Vehicle.new(Vehicle, speed) -- Panggil constructor induk
obj.brand = brand -- Tambahkan field khusus turunan
setmetatable(obj, Car) -- Hubungkan kembali ke Car
return obj
endPerhatikan langkah-langkah utama dalam constructor child: pertama, kita memanggil Vehicle.new(Vehicle, speed) untuk mendapatkan object dengan field speed yang sudah ditetapkan. Lalu kita menambahkan field brand khusus child. Terakhir, kita mengubah metatable dari Vehicle menjadi Car agar instance mencari method di class child terlebih dahulu.
Kamu juga dapat menggunakan sintaks titik dua saat memanggil konstruktor induk: Vehicle:new(speed) setara dengan Vehicle.new(Vehicle, speed), karena keduanya meneruskan Vehicle sebagai argumen pertama. Kedua bentuk ini berfungsi dengan benar di sini, jadi silakan gunakan bentuk yang menurutmu lebih mudah dibaca.
local myCar = Car:new(120, "Toyota")
print(myCar.speed) -- output: 120
print(myCar.brand) -- output: ToyotaPola ini membuat kodemu tetap DRY: logika inisialisasi bersama berada di parent, sementara setiap child hanya menangani atribut uniknya.
Tantangan
MudahMari kita bangun hierarki makhluk hidup dengan class turunan yang memperluas konstruktor class induknya! Kamu akan membuat class induk Animal dan class turunan Bird. Konstruktor Bird akan memanggil konstruktor Animal untuk menangani inisialisasi bersama sebelum menambahkan atribut uniknya sendiri.
Kamu akan mengatur kodemu di tiga file:
Animal.lua: Definisikan class induk dengan konstruktor:new(name)yang menyimpan nama hewan. Sertakan method:describe()yang mencetak nama hewan. Siapkan pola class standar dengan__indexdan kembalikan class tersebut.Bird.lua: Definisikan class turunan yang mewarisi Animal. Konstruktor:new(name, wingspan)milik Bird harus memanggil konstruktor induk menggunakanAnimal.new(Animal, name)untuk menginisialisasi nama, lalu menambahkan fieldwingspanke object, dan terakhir mengatur ulang metatable ke Bird. Sertakan method:info()yang mencetak nama dan rentang sayap dalam format tertentu.main.lua: Muat module Bird, baca dua input (nama dan rentang sayap), buat instance Bird, lalu panggil kedua method untuk menunjukkan bahwa fungsi turunan dan fungsi khusus class anak bekerja bersama.
Kamu akan menerima dua input:
- Nama burung
- Rentang sayap burung (sebuah angka)
Di file utama, buat Bird dengan nama dan rentang sayap yang diberikan. Lalu panggil :describe() diikuti :info() pada baris terpisah.
Method :describe() (yang diwarisi dari Animal) harus mencetak:
Animal: {name}Method :info() (yang didefinisikan di Bird) harus mencetak:
{name} has a wingspan of {wingspan}Misalnya, jika inputnya adalah Eagle dan 200, outputnya harus seperti berikut:
Animal: Eagle
Eagle has a wingspan of 200Hal penting di sini adalah konstruktor Bird tidak mengulang inisialisasi nama. Konstruktor ini menyerahkan pekerjaan tersebut kepada konstruktor Animal, lalu hanya menambahkan hal yang unik pada burung. Cara ini membuat kodemu tetap DRY sekaligus membangun rantai pewarisan yang tepat!
Coba sendiri
-- main.lua: Titik awal program
local Bird = require('Bird')
-- Baca input
local name = io.read()
local wingspan = tonumber(io.read())
-- TODO: Buat instance Bird dengan nama dan rentang sayap yang diberikan
-- TODO: Panggil :describe() pada burung tersebut (diwarisi dari Animal)
-- TODO: Panggil :info() pada burung tersebut (didefinisikan dalam Bird)
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