# Modul Pembelajaran: PHP Interfaces

## Bagian 1: Konsep Dasar

### 1.1. Apa itu Interface?
**Interface** adalah sebuah "kontrak" dalam pemrograman berorientasi objek. Ia mendefinisikan method apa saja yang **harus** dimiliki oleh sebuah class, tanpa memberitahu bagaimana method tersebut harus bekerja.

Analogi yang paling mudah adalah **Stopkontak Listrik**.
-   Stopkontak adalah interface. Ia menjanjikan dua lubang dengan tegangan 220V.
-   Kipas Angin, TV, dan Laptop adalah class yang mengimplementasikan interface tersebut (punya steker).
-   Stopkontak tidak peduli benda apa yang dicolokkan, asalkan steker-nya cocok, listrik akan mengalir.

### 1.2. Syntax Dasar
Interface didefinisikan dengan keyword `interface`. Semua method di dalamnya otomatis bersifat `public` dan `abstract` (tanpa body).

```php
interface Logger {
    public function log($message);
}
```

Untuk menggunakan interface, sebuah class menggunakan keyword `implements`.

```php
class FileLogger implements Logger {
    public function log($message) {
        echo "Menulis ke file: $message";
    }
}
```

---

## Bagian 2: Multiple Inheritance

### 2.1. Keterbatasan Class
PHP menganut **Single Inheritance**, artinya sebuah class hanya boleh punya satu parent (`extends SatuClass`). Ini kadang membatasi jika kita ingin sebuah class mewarisi sifat dari dua sumber berbeda.

### 2.2. Solusi Interface
Interface memecahkan masalah ini. Sebuah class boleh mengimplementasikan **Banyak Interface** sekaligus.

```php
interface CanFly { public function fly(); }
interface CanSwim { public function swim(); }

class Duck implements CanFly, CanSwim {
    public function fly() { echo "Terbang..."; }
    public function swim() { echo "Berenang..."; }
}
```

---

## Bagian 3: Interface vs Abstract Class

Ini adalah pertanyaan wawancara kerja yang paling sering muncul.

| Fitur | Interface | Abstract Class |
| :--- | :--- | :--- |
| **Implementasi** | Tidak boleh ada logic sama sekali (hanya deklarasi method). | Boleh ada method biasa dengan logic lengkap. |
| **Properti** | Hanya boleh konstanta (`const`). | Boleh variabel (`public`, `protected`, `private`). |
| **Inheritance** | Multiple (`implements A, B`). | Single (`extends A`). |
| **Visibilitas** | Semua method wajib `public`. | Method bisa `public`, `protected`, `private`. |
| **Filosofi** | "Can-do" (Kemampuan). Contoh: `CanFly`, `Loggable`. | "Is-a" (Identitas). Contoh: `Animal`, `Vehicle`. |

---

## Bagian 4: Polymorphism & Type Hinting

Kekuatan terbesar interface ada pada **Type Hinting**. Kita bisa memaksa sebuah fungsi untuk menerima parameter berupa Interface, bukan Class konkret. Ini membuat kode sangat fleksibel (Loose Coupling).

### Contoh Kasus: User Profile Update
Bayangkan kita punya fungsi untuk update profil user, dan kita ingin mencatat log aktivitasnya.

**Cara Kaku (Tanpa Interface):**
```php
function updateProfile(FileLogger $logger) {
    // ... update logic
    $logger->log("Updated");
}
```
Masalah: Fungsi ini HANYA mau menerima `FileLogger`. Kalau besok kita mau ganti simpan log ke Database (`DatabaseLogger`), kita harus ubah kode fungsi `updateProfile`.

**Cara Fleksibel (Dengan Interface):**
```php
function updateProfile(Logger $logger) {
    // ... update logic
    $logger->log("Updated");
}
```
Solusi: Fungsi ini sekarang menerima APAPUN yang mengimplementasikan `Logger`. Bisa `FileLogger`, `DatabaseLogger`, atau `EmailLogger`. Kita bisa ganti-ganti logger tanpa menyentuh kode `updateProfile` sama sekali.

---

## Bagian 5: Real World Example (Repository Pattern)

Repository Pattern adalah standar industri untuk memisahkan logika aplikasi dari logika database.

1.  Buat Interface `UserRepository`:
    ```php
    interface UserRepository {
        public function find($id);
        public function save($user);
    }
    ```

2.  Buat Implementasi MySQL:
    ```php
    class MySQLUserRepository implements UserRepository {
        public function find($id) { /* Query MySQL */ }
        public function save($user) { /* Insert MySQL */ }
    }
    ```

3.  Gunakan di Controller dengan Type Hint Interface:
    ```php
    class UserController {
        private $repo;
        
        public function __construct(UserRepository $repo) {
            $this->repo = $repo;
        }
        
        public function show($id) {
            $user = $this->repo->find($id);
            // ...
        }
    }
    ```

Jika suatu saat Anda ingin pindah dari MySQL ke MongoDB, Anda cukup buat class `MongoUserRepository` yang implements `UserRepository`, lalu ganti di konfigurasi dependency injection. Kode Controller tidak perlu diubah satu baris pun!
