28. Banyak objek sekaligus

Bab 26 dan 27 membuat satu objek dalam satu waktu. Class justru paling berguna saat ada banyak objek dari jenis yang sama diperlakukan sebagai kelompok: sekelompok karakter, sekawanan musuh. Bab ini menggabungkan dua hal yang sudah kamu tahu — class (Bab 27) dan daftar (Bab 22) — menjadi pola sehari-hari berupa daftar objek.

Sebuah class untuk membuat banyak objek

Class Critter kecil — sebuah constructor dan dua method, mengikuti pola Bab 27.

local Critter = {}
Critter.__index = Critter

function Critter.new(name, energy)
    local self = setmetatable({}, Critter)
    self.name = name
    self.energy = energy
    return self
end

function Critter:play()
    self.energy = self.energy - 1
    print(self.name .. " plays. Energy: " .. self.energy)
end

function Critter:isTired()
    return self.energy <= 0
end

Simpan objek-objek dalam sebuah daftar

Setiap Critter.new(...) mengembalikan satu instance baru. Simpan beberapa sekaligus dalam sebuah daftar, seperti nilai apapun:

local critters = {
    Critter.new("Spark", 3),
    Critter.new("Bolt", 2),
    Critter.new("Nova", 1),
}

critters adalah daftar biasa (Bab 22). Yang baru adalah bahwa setiap item adalah sebuah objek dengan state dan method-nya sendiri.

Perulangan dan memanggil method pada setiap objek

Telusuri daftar dengan ipairs dan panggil sebuah method pada setiap objek. Masing-masing bekerja pada datanya sendiri:

for _, c in ipairs(critters) do
    c:play()
end

Keluaran:

Spark plays. Energy: 2
Bolt plays. Energy: 1
Nova plays. Energy: 0

Satu perulangan, tiga objek, tiga nilai energi yang terpisah. Inilah inti dari kode berorientasi objek: simpan sebuah koleksi, lakukan aksi padanya sebagai kelompok, dan biarkan setiap objek melacak dirinya sendiri.

Buka exercises/28/01-critters.lua. File ini membuat daftar critter dan membuat masing-masing bermain sekali. Tambahkan perulangan kedua agar masing-masing bermain lagi, dan perhatikan nilai energinya turun.

Memfilter dan menghitung objek

Karena ini hanya sebuah daftar, setiap pola perulangan dari Bab 20 juga berlaku untuk objek. Hitung berapa banyak critter yang kelelahan:

local tired = 0
for _, c in ipairs(critters) do
    if c:isTired() then
        tired = tired + 1
    end
end
print(tired .. " critters need a rest.")   -- 1 critters need a rest.

Kondisi if memanggil sebuah method (c:isTired()) alih-alih memeriksa field biasa, tapi pola menghitungnya tidak berubah.

Menambah dan menghapus objek

table.insert dan table.remove (Bab 24) bekerja pada daftar objek sama seperti daftar angka:

table.insert(critters, Critter.new("Zip", 5))   -- a new critter joins
table.remove(critters, 1)                        -- the first one leaves

Objek adalah nilai seperti nilai lainnya — bisa ditambah, dihapus, diurutkan, dan dihitung.

PR

File PR ada di exercises/28/homework/.

Soal 1 — Sekelompok pahlawan

Buka exercises/28/homework/01-party.lua. Sebuah class Hero kecil sudah disediakan. Buat daftar tiga pahlawan dengan nama dan hit point yang berbeda, lalu lakukan perulangan pada daftar tersebut dan cetak nama serta HP masing-masing di barisnya sendiri.

Soal 2 — Total HP

Buka exercises/28/homework/02-total-hp.lua. Gunakan pola akumulasi untuk menjumlahkan HP semua orang dan cetak total tim tersebut.

Soal 3 — Siapa yang terluka?

Buka exercises/28/homework/03-who-is-hurt.lua. Setiap pahlawan memiliki hp dan max_hp. Lakukan perulangan pada kelompok tersebut dan cetak setiap pahlawan yang hp-nya berada di bawah max_hp.

Tantangan — Pahlawan terkuat

Buka exercises/28/homework/04-strongest.lua. Lakukan perulangan pada kelompok tersebut dan cetak nama pahlawan dengan HP terbanyak. Gunakan ide akumulasi-nilai-maksimum: ingat yang terbaik sejauh ini, gantikan saat kamu menemukan yang lebih kuat.

Bingung atau sudah selesai? Buka halaman solusi PR.