interface Mesin {
    void nyalakan();

    String jenis();
}

class MesinBensin implements Mesin {
    @Override
    public void nyalakan() {
        System.out.println("Mesin bensin menyala, idle 800 rpm");
    }

    @Override
    public String jenis() {
        return "bensin";
    }
}

class MesinListrik implements Mesin {
    @Override
    public void nyalakan() {
        System.out.println("Mesin listrik siap, senyap");
    }

    @Override
    public String jenis() {
        return "listrik";
    }
}

// Versi komposisi: Mobil MEMILIKI (has-a) Mesin, bukan MERUPAKAN (is-a) Mesin.
class Mobil {
    private final String pemilik;
    private Mesin mesin;

    public Mobil(String pemilik, Mesin mesin) {
        this.pemilik = pemilik;
        this.mesin = mesin;
    }

    // Delegasi: method Mobil menyerahkan pekerjaan ke objek mesin.
    public void berangkat() {
        System.out.print(pemilik + ": ");
        mesin.nyalakan();
    }

    // Keuntungan komposisi: mesin bisa dipasang ulang saat runtime.
    public void pasangMesin(Mesin mesinBaru) {
        this.mesin = mesinBaru;
        System.out.println(pemilik + " memasang mesin " + mesinBaru.jenis());
    }
}

public class MobilKomposisi {
    public static void main(String[] args) {
        Mobil mobilBudi = new Mobil("Budi", new MesinBensin());
        mobilBudi.berangkat();

        mobilBudi.pasangMesin(new MesinListrik());
        mobilBudi.berangkat();
    }
}
