Tutorial PHP #23: Interface, Trait, dan Abstract Class
1. Abstract Class
Abstract class adalah class yang tidak bisa diinstansiasi langsung - harus di-extend dulu. Digunakan sebagai template untuk class-class yang punya karakteristik serupa tapi berbeda implementasinya.
<?php
abstract class Bentuk {
// Abstract method: tidak punya implementasi, wajib di-override child class
abstract public function luas(): float;
abstract public function keliling(): float;
// Method biasa: punya implementasi, bisa dipakai langsung
public function info(): string {
return "Luas: {$this->luas()}, Keliling: {$this->keliling()}";
}
}
class Persegi extends Bentuk {
public function __construct(private float $sisi) {}
public function luas(): float {
return $this->sisi ** 2;
}
public function keliling(): float {
return 4 * $this->sisi;
}
}
class Lingkaran extends Bentuk {
public function __construct(private float $radius) {}
public function luas(): float {
return M_PI * $this->radius ** 2;
}
public function keliling(): float {
return 2 * M_PI * $this->radius;
}
}
$persegi = new Persegi(5);
$lingkaran = new Lingkaran(7);
echo $persegi->info(); // Output: Luas: 25, Keliling: 20
echo $lingkaran->info(); // Output: Luas: 153.938..., Keliling: 43.982...
// $bentuk = new Bentuk(); // ERROR! Tidak bisa instansiasi abstract class
?>
2. Interface
Interface mendefinisikan "kontrak" - daftar method yang wajib diimplementasikan oleh class yang menggunakannya. Semua method di interface harus public.
<?php
interface Serializable {
public function toArray(): array;
public function toJson(): string;
}
interface Validatable {
public function validate(): bool;
public function getErrors(): array;
}
// Satu class bisa implement banyak interface
class FormData implements Serializable, Validatable {
private array $errors = [];
public function __construct(
private string $nama,
private string $email
) {}
public function toArray(): array {
return ["nama" => $this->nama, "email" => $this->email];
}
public function toJson(): string {
return json_encode($this->toArray());
}
public function validate(): bool {
$this->errors = [];
if (empty($this->nama)) $this->errors[] = "Nama wajib diisi";
if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
$this->errors[] = "Email tidak valid";
}
return empty($this->errors);
}
public function getErrors(): array {
return $this->errors;
}
}
$form = new FormData("Ariq", "ariq@mail.com");
if ($form->validate()) {
echo $form->toJson();
// Output: {"nama":"Ariq","email":"ariq@mail.com"}
}
?>
3. Trait
Trait memungkinkan berbagi kode (method) ke beberapa class tanpa inheritance. Solusi untuk masalah PHP yang tidak mendukung multiple inheritance.
<?php
trait Timestamps {
private ?string $createdAt = null;
private ?string $updatedAt = null;
public function setCreatedAt(): void {
$this->createdAt = date("Y-m-d H:i:s");
}
public function setUpdatedAt(): void {
$this->updatedAt = date("Y-m-d H:i:s");
}
public function getCreatedAt(): ?string { return $this->createdAt; }
public function getUpdatedAt(): ?string { return $this->updatedAt; }
}
trait SoftDelete {
private bool $deleted = false;
public function delete(): void {
$this->deleted = true;
}
public function isDeleted(): bool {
return $this->deleted;
}
public function restore(): void {
$this->deleted = false;
}
}
class Artikel {
use Timestamps, SoftDelete; // pakai dua trait sekaligus!
public function __construct(public string $judul) {
$this->setCreatedAt();
}
}
$artikel = new Artikel("Belajar PHP OOP");
echo $artikel->getCreatedAt(); // Output: timestamp saat ini
echo $artikel->isDeleted(); // Output: false (belum dihapus)
$artikel->delete();
echo $artikel->isDeleted(); // Output: true
?>
4. Kapan Pakai Masing-Masing?
- Abstract class - ada kode yang bisa dishare, tapi tiap turunan punya implementasi berbeda
- Interface - mendefinisikan kontrak tanpa implementasi, class bisa implement banyak interface
- Trait - ingin berbagi method ke beberapa class yang tidak ada hubungan inheritance
5. Ringkasan
- Abstract class tidak bisa diinstansiasi, gunakan sebagai template class
- Interface mendefinisikan kontrak method yang wajib diimplementasikan
- Trait untuk code reuse di class yang berbeda tanpa inheritance langsung
- Satu class bisa implement banyak interface tapi hanya extend satu class
Tutorial berikutnya membahas namespace dan autoloading.
.jpg)
