OOP II: Inheritance, Abstract, Interface & Trait

Pewarisan, method override, class abstrak, interface, trait, polimorfisme, dan kapan memakai komposisi.

Part 10 dari 22 ± 55 menit Gratis

Inheritance (pewarisan)

Class anak dapat mewarisi properti & method class induk memakai extends, lalu menambah atau mengganti (override) perilaku.

class Hewan
{
    public function __construct(protected string $nama) {}

    public function suara(): string
    {
        return '...';
    }

    public function perkenalan(): string
    {
        return "{$this->nama} berkata {$this->suara()}";
    }
}

class Kucing extends Hewan
{
    public function suara(): string
    {
        return 'meong';
    }
}

echo (new Kucing('Mimi'))->perkenalan();   // Mimi berkata meong

parent::suara() memanggil versi induk. Tandai final pada class/method yang tidak boleh diturunkan atau di-override. PHP 8.3 menambah atribut #[\Override] agar PHP memeriksa bahwa method memang menimpa method induk (menangkap salah ketik nama).

Class abstrak

abstract class Bentuk
{
    abstract public function luas(): float;       // wajib diimplementasikan anak

    public function deskripsi(): string
    {
        return sprintf('%s dengan luas %.2f', static::class, $this->luas());
    }
}

Class abstrak tidak bisa di-new langsung; ia adalah kerangka setengah jadi untuk turunannya.

Interface — kontrak

interface BisaTerbang { public function terbang(): string; }
interface BisaBerenang { public function renang(): string; }

class Bebek extends Hewan implements BisaTerbang, BisaBerenang
{
    public function terbang(): string { return 'mengepak'; }
    public function renang(): string  { return 'berenang'; }
}

Interface hanya mendeklarasikan apa yang bisa dilakukan, bukan bagaimana. Satu class boleh mengimplementasikan banyak interface (tetapi mewarisi satu class saja). Interface membuat kode longgar terikat: fungsi yang menerima PembayaranInterface bisa bekerja dengan Transfer, Kartu, atau QRIS tanpa tahu detailnya.

Polimorfisme

interface Pembayaran { public function bayar(int $jumlah): string; }

class Transfer implements Pembayaran { public function bayar(int $jumlah): string { return "Transfer Rp{$jumlah}"; } }
class Qris implements Pembayaran     { public function bayar(int $jumlah): string { return "QRIS Rp{$jumlah}"; } }

function checkout(Pembayaran $metode, int $total): string
{
    return $metode->bayar($total);    // tidak peduli kelas konkretnya
}

Trait — berbagi kode horizontal

trait MencatatWaktu
{
    public ?string $dibuatPada = null;

    public function tandaiDibuat(): void
    {
        $this->dibuatPada = date('c');
    }
}

class Artikel { use MencatatWaktu; }
class Komentar { use MencatatWaktu; }

Trait menyalin method ke dalam class yang memakainya — berguna untuk perilaku yang dipakai banyak class tanpa hubungan pewarisan (timestamp, logging). Jangan berlebihan; trait yang besar membuat alur sulit dilacak.

Komposisi lebih baik dari pewarisan

Pewarisan yang dalam membuat kode kaku. Aturan praktis: pakai extends untuk hubungan "adalah" yang sungguh-sungguh (Kucing adalah Hewan); untuk hubungan "memiliki / memakai", suntikkan objek lain lewat constructor (dependency injection):

class PesananService
{
    public function __construct(private Pembayaran $metode) {}

    public function proses(int $total): string
    {
        return $this->metode->bayar($total);
    }
}

Prinsip SOLID singkat

  • S — satu class, satu tanggung jawab
  • O — terbuka untuk ditambah, tertutup untuk diubah
  • L — turunan harus bisa menggantikan induk
  • I — interface kecil dan fokus
  • D — bergantung pada abstraksi (interface), bukan class konkret

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X