# Modul Pembelajaran: PHP Abstract Class

## Bagian 1: Konsep Abstraksi

### 1.1. Apa itu Abstraksi?
Dalam dunia nyata, kita berinteraksi dengan banyak benda kompleks tanpa perlu memahami detail cara kerjanya. Contohnya mobil. Untuk mengendarai mobil, kita cukup tahu cara menggunakan setir, pedal gas, dan rem. Kita tidak perlu tahu bagaimana piston bergerak atau bagaimana sistem injeksi bahan bakar bekerja.

Inilah **Abstraksi**: Menyembunyikan detail implementasi yang rumit dan hanya menampilkan fungsionalitas yang relevan bagi pengguna.

### 1.2. Abstraksi dalam OOP
Dalam Pemrograman Berorientasi Objek (OOP), abstraksi dicapai dengan menggunakan **Abstract Class** dan **Interface**. Tujuannya adalah untuk membuat kerangka kerja (blueprint) yang jelas dan memisahkan "apa yang harus dilakukan" dari "bagaimana cara melakukannya".

---

## Bagian 2: Abstract Class

### 2.1. Definisi
**Abstract Class** adalah sebuah class yang tidak dapat diinstansiasi (tidak bisa dibuat object-nya secara langsung). Ia dirancang khusus untuk menjadi parent class bagi class lain.

### 2.2. Karakteristik Utama
1.  **Keyword `abstract`**: Dideklarasikan dengan keyword `abstract`.
2.  **Tidak bisa di-new**: `new Kendaraan()` akan menyebabkan error jika `Kendaraan` adalah abstract class.
3.  **Bisa punya method biasa**: Abstract class boleh memiliki method dengan implementasi lengkap (method biasa) dan properti.
4.  **Bisa punya Abstract Method**: Ini adalah fitur kuncinya.

### 2.3. Contoh Syntax
```php
abstract class Kendaraan {
    protected $warna;

    public function setWarna($warna) {
        $this->warna = $warna;
    }

    // Abstract method (tanpa body)
    abstract public function bergerak();
}
```

---

## Bagian 3: Abstract Method

### 3.1. Apa itu Abstract Method?
Abstract method adalah method yang hanya memiliki deklarasi (nama, parameter, dan return type hint) tetapi **tidak memiliki body** (tidak ada kurung kurawal `{}`).

### 3.2. Aturan Implementasi
Jika sebuah class memiliki minimal satu abstract method, maka class tersebut **WAJIB** menjadi abstract class.

Class turunan (Concrete Class) yang meng-extends abstract class **WAJIB** mengimplementasikan (meng-override) seluruh abstract method yang ada di parent-nya. Jika tidak, class turunan tersebut juga harus menjadi abstract class.

### 3.3. Contoh Implementasi
```php
class Mobil extends Kendaraan {
    // Wajib implementasi method bergerak()
    public function bergerak() {
        echo "Mobil melaju dengan roda.";
    }
}

class Pesawat extends Kendaraan {
    // Wajib implementasi method bergerak()
    public function bergerak() {
        echo "Pesawat terbang di udara.";
    }
}
```

---

## Bagian 4: Studi Kasus

### 4.1. Studi Kasus: Shape (Bangun Datar)
Bayangkan kita ingin membuat aplikasi untuk menghitung luas berbagai bentuk.
-   Setiap bentuk pasti punya warna.
-   Setiap bentuk pasti punya luas.
-   TAPI, cara menghitung luas Lingkaran beda dengan Persegi.

Solusi: Buat `Shape` sebagai abstract class dengan abstract method `calculateArea()`.

```php
abstract class Shape {
    protected $color;
    public function __construct($color) { $this->color = $color; }
    
    abstract public function calculateArea(); // Paksa anak untuk buat rumus sendiri
}

class Circle extends Shape {
    private $radius;
    public function __construct($color, $radius) {
        parent::__construct($color);
        $this->radius = $radius;
    }
    public function calculateArea() {
        return pi() * pow($this->radius, 2);
    }
}
```

### 4.2. Studi Kasus: Payment Gateway
Aplikasi e-commerce mendukung pembayaran via PayPal, Stripe, dan Transfer Bank. Semua metode pembayaran punya alur yang sama: "Proses Pembayaran".

```php
abstract class Payment {
    abstract public function process($amount);
}

class PayPalPayment extends Payment {
    public function process($amount) {
        // Connect ke API PayPal...
    }
}
```

Dengan cara ini, di kode utama kita bisa menggunakan **Polimorfisme**:
```php
function checkout(Payment $method, $amount) {
    $method->process($amount);
}
```
Fungsi `checkout` tidak peduli apakah itu PayPal atau Stripe, yang penting itu adalah turunan dari `Payment`.

---

## Bagian 5: Abstract Class vs Interface

| Fitur | Abstract Class | Interface |
| :--- | :--- | :--- |
| **Method Body** | Boleh ada (untuk method non-abstract) | Tidak boleh (sebelum PHP 8) |
| **Properties** | Boleh punya variabel/state | Hanya konstanta |
| **Inheritance** | Single Inheritance (`extends`) | Multiple Inheritance (`implements`) |
| **Visibilitas** | Public, Protected, Private | Public only |
| **Tujuan** | Menyediakan fungsionalitas dasar (Base Class) | Mendefinisikan kontrak (Contract) |

**Kapan pakai Abstract Class?**
Gunakan saat class-class turunan memiliki banyak kesamaan kode (share logic) dan memiliki hubungan "is-a" yang kuat (Mobil *adalah* Kendaraan).

**Kapan pakai Interface?**
Gunakan saat Anda ingin menetapkan standar kemampuan yang bisa dimiliki oleh class yang berbeda-beda, tanpa peduli hierarkinya (hubungan "can-do").
