Abstract class di PHP dideklarasikan dengan abstract class Name dan tidak bisa dibuat dengan new. Class ini menjadi dasar untuk class lain: isinya bisa property, constructor, dan method yang sudah lengkap, ditambah method abstract tanpa body yang wajib diimplementasikan oleh setiap class turunan.
describe() ditulis sekali di Shape dan memanggil area(), yang disediakan oleh setiap class turunan. Abstract class menjamin method itu ada, jadi describe() bisa mengandalkannya.
Abstract class tidak bisa dibuat dengan new
Abstract class sengaja dibuat tidak lengkap: Shape::area() tidak punya body, jadi objek Shape biasa tidak punya apa pun untuk dijalankan. PHP menolak membuatnya dan melempar Error:
Abstract method: aturannya
Abstract method punya signature dan titik koma, bukan body. Setiap class turunan harus mengimplementasikannya dengan signature yang kompatibel dan visibilitas yang sama atau lebih luas: method abstract protected boleh menjadi protected atau public di class turunan, tetapi tidak pernah private. Class yang punya satu saja abstract method wajib dideklarasikan abstract juga.
Class turunan yang melewatkan sebuah abstract method akan menghentikan script sebelum satu baris pun berjalan, kecuali class turunan itu juga dideklarasikan abstract dan menyerahkan method tersebut ke turunannya sendiri:
PHP Fatal error: Class Square contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Shape::area) in /home/index.php on line 3
Pola template method
Alasan paling umum untuk menulis abstract class: ada urutan langkah yang tetap, dan hanya beberapa langkah yang berbeda. Class dasar memegang urutannya di sebuah method final, lalu class turunan mengisi langkah-langkahnya. Di sini laporan yang sama dijalankan sebagai teks biasa dan sebagai tabel HTML:
Jalankan, dan tab Halaman menampilkan tabel HTML di atas versi teks biasanya. open() dan close() punya body bawaan, jadi hanya HtmlReport yang perlu meng-override keduanya; row() dibuat abstract karena tidak ada nilai bawaan yang masuk akal. Menjadikan render() sebagai final mencegah class turunan mengubah urutan langkahnya.
Abstract class bisa mengimplementasikan interface
Abstract class boleh mendeklarasikan implements dan menyerahkan sebagian method dari interface itu ke class turunannya. Ini cara standar untuk memasangkan interface (tipenya) dengan class dasar (kode bersamanya):
Kode memakai type hint ke interface Cache, jadi class yang tidak bisa meng-extend BaseCache (karena sudah meng-extend class lain) tetap bisa mengimplementasikan Cache secara langsung.
Kapan memakai abstract class, dan kapan tidak
Pakai abstract class saat class dalam satu keluarga berbagi kode nyata: property, constructor, method yang sama untuk semuanya. Kalau class dasarnya hanya berisi abstract method, itu sebenarnya interface yang menyamar, dan interface adalah pilihan yang lebih baik karena sebuah class bisa mengimplementasikan banyak interface tetapi hanya bisa meng-extend satu class. Kalau kamu hanya ingin berbagi beberapa method bantu antar-class yang tidak berhubungan, pakai trait daripada memaksa semuanya di bawah satu induk.
Tes cepat sebelum menulis abstract class: apakah setiap class turunan benar-benar sejenis dengan class dasarnya (Circle adalah sebuah Shape)? Kalau jawaban jujurnya "ia bisa melakukan ini" alih-alih "ia adalah salah satu dari ini", tulislah interface.
Pertanyaan yang sering diajukan
Apa itu abstract class di PHP?
Class yang dideklarasikan dengan abstract class Name dan tidak bisa dibuat dengan new. Class ini menjadi dasar untuk class lain: isinya bisa property, constructor, dan method biasa, dan ia bisa mendeklarasikan method abstract yang wajib diimplementasikan oleh setiap class turunan.
Apa itu abstract method di PHP?
Method yang dideklarasikan dengan abstract dan tanpa body: abstract protected function render(array $rows): string;. Class yang memuat method seperti ini wajib dideklarasikan abstract juga, dan setiap class turunan yang tidak abstract harus mendefinisikan method dengan signature yang kompatibel.
Apakah abstract class di PHP boleh punya constructor?
Boleh. Kamu tidak bisa memanggil new pada abstract class, tetapi constructor-nya tetap berjalan saat class turunan dibuat, entah otomatis (kalau class turunan tidak punya constructor) atau lewat parent::__construct(...).
Apakah abstract class di PHP bisa diinstansiasi?
Tidak. new Shape() pada abstract class melempar Error: Cannot instantiate abstract class Shape. Buatlah objek dari class turunan yang konkret, misalnya new Circle(2).
Kapan sebaiknya memakai abstract class di PHP?
Saat beberapa class yang berkaitan berbagi kode nyata (property, constructor, method yang sama) dan hanya berbeda di beberapa langkah. Taruh kode bersama di abstract class dan deklarasikan langkah yang berbeda sebagai abstract. Kalau tidak ada kode bersama dan kamu hanya butuh kontrak, pakai interface.