Interface vs Abstract Class
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 30 dari 91.
Sekarang setelah kamu mempelajari interface dan abstract class, mari kita perjelas kapan harus menggunakan masing-masing. Keduanya mungkin tampak serupa, tetapi memiliki tujuan yang berbeda dan kemampuan yang berbeda.
| Fitur | Interface | Class Abstrak |
|---|---|---|
| Method | Hanya signature method | Method abstrak dan konkret |
| Property | Hanya konstanta | Dapat memiliki property |
| Multiple inheritance | Sebuah class dapat mengimplementasikan banyak interface | Sebuah class hanya dapat mewarisi satu class |
| Konstruktor | Dapat mendeklarasikan signature __construct (tanpa isi) | Dapat mendefinisikan konstruktor dengan isi |
Gunakan interface saat kamu ingin menetapkan kontrak yang dapat dipenuhi oleh class yang tidak saling terkait. Misalnya, Printer dan Logger sama-sama dapat mengimplementasikan interface Writable, meskipun keduanya tidak memiliki leluhur yang sama.
Gunakan class abstrak ketika kamu memiliki class yang saling berkaitan dan berbagi kode yang sama. Jika class Dog dan Cat sama-sama memerlukan implementasi method eat() yang sama, class Animal abstrak memungkinkan kamu menulis kode itu sekali saja.
Kamu juga bisa menggabungkan kedua pendekatan. Sebuah class dapat mewarisi abstract class sekaligus mengimplementasikan beberapa interface:
<?php
abstract class Animal {
protected $name;
public function eat() {
return $this->name . " is eating";
}
}
interface Swimmable {
public function swim();
}
class Duck extends Animal implements Swimmable {
public function __construct($name) {
$this->name = $name;
}
public function swim() {
return $this->name . " is swimming";
}
}
Poin Utama: Pilih interface untuk mendefinisikan kemampuan yang digunakan oleh class yang tidak saling terkait. Pilih class abstrak saat kamu perlu berbagi kode di antara class yang saling terkait.
Tantangan
MudahMari kita buat sistem kendaraan yang menunjukkan kapan harus menggunakan abstract class dibandingkan interface, dan cara menggabungkan kedua pendekatan tersebut secara efektif.
Kamu akan membuat sistem tempat kendaraan berbagi property umum melalui pewarisan, tetapi juga bisa memperoleh kemampuan tambahan melalui interface. Ini mencerminkan keputusan desain di dunia nyata: mobil "adalah" kendaraan (pewarisan), tetapi juga "memiliki kemampuan" untuk diisi bahan bakar (interface).
Atur kodemu dalam empat file:
Refuelable.php: Definisikan interfaceRefuelabledengan satu tanda tangan method:refuel($amount). Kemampuan ini dapat diterapkan pada class apa pun yang perlu diisi bahan bakar, apa pun hierarki pewarisannya.Vehicle.php: Definisikan abstract classVehicleyang menyediakan fungsionalitas bersama untuk semua kendaraan. Class ini harus memiliki property$brandyang dilindungi dan property$fuelLevelyang dilindungi (dimulai dari 0). Constructor menerima nama merek. Sertakan method konkretgetBrand()yang mengembalikan merek, method konkretgetFuelLevel()yang mengembalikan tingkat bahan bakar saat ini, serta method abstrakdrive()yang harus diimplementasikan oleh class turunan.Car.php: Buat classCaryang mewarisiVehicledan mengimplementasikanRefuelable. Sertakan kedua file yang diperlukan di bagian atas. Constructor menerima merek dan meneruskannya ke constructor induk. Implementasikandrive()agar mengembalikan"[brand] car is driving". Implementasikanrefuel($amount)untuk menambahkan jumlah tersebut ke tingkat bahan bakar dan mengembalikan"[brand] refueled to [fuelLevel] liters".main.php: Sertakan file Car. Kamu akan menerima dua input: nama merek dan jumlah bahan bakar (konversikan menjadi bilangan bulat). BuatCardengan merek tersebut. Cetak hasildrive()pada baris pertama, lalu cetak hasilrefuel()dengan jumlah bahan bakar pada baris kedua.
Tantangan ini menggambarkan perbedaan utama: abstract class Vehicle berbagi kode dan membentuk hubungan "is-a", sedangkan interface Refuelable menambahkan kemampuan yang dapat diterapkan pada class lain yang tidak berkaitan (seperti generator atau perahu) tanpa mengharuskan class tersebut menjadi kendaraan.
Coba sendiri
<?php
require_once 'Car.php';
// Baca input
$brand = trim(fgets(STDIN));
$fuelAmount = intval(trim(fgets(STDIN)));
// TODO: Buat Car dengan merek tersebut
// TODO: Tampilkan hasil drive() pada baris pertama
// TODO: Tampilkan hasil refuel() dengan jumlah bahan bakar pada baris kedua
?>Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengenalan OOPclass vs objectKata Kunci $thismethodpropertyConstructor (__construct)Destructor (__destruct)Ringkasan: Kalkulator Sederhana4Pewarisan
Pewarisan DasarKata Kunci parent::Penimpaan methodKata Kunci finalClass AbstrakRingkasan: Hierarki Karyawan7Enkapsulasi
Public, Protected, PrivateModifier Akses secara MendalamGetter dan SetterPenyembunyian InformasiPromosi Constructor (8.0)Ulasan: Sistem Catatan Siswa2Namespace dan Autoloading
Pengenalan NamespaceKata Kunci useStandar Autoloading PSR-4Autoloader ComposerRingkasan: Proyek yang Terorganisasi5Interface dan Kontrak
Pengenalan InterfaceMengimplementasikan InterfaceImplementasi Beberapa InterfaceInterface vs Abstract ClassPetunjuk Tipe dengan InterfaceRekap: Kalkulator Bentuk8Magic Methods
Pengantar Magic Methods__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Cloning Object__serialize & __unserializeRingkasan: Koleksi Kustom11Sistem Tipe Data dan Penanganan Error
Deklarasi TipeTipe NullableTipe Union dan IntersectionClass ExceptionHierarki Exception KustomTry, Catch, FinallyRekap: Validator Form3Property dalam class
Property instance vs staticKonstanta dalam classMethod & property staticProperty private & protectedProperty readonly (PHP 8.1)Ulasan: Pengelola Rekening Bank6Polimorfisme
Meninjau Kembali Method OverridingPolimorfisme melalui AntarmukaPetunjuk Tipe dan Tipe UnionPengikatan Statis TertundaRangkuman: Pemroses PembayaranLatihan sendiri: Compiler PHP online