Menu
CoddyTech

Polimorfisme melalui Antarmuka

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 34 dari 91.

Di pelajaran sebelumnya, kamu melihat polimorfisme melalui pewarisan, ketika class anak menimpa method dari class induk. Interface menyediakan cara ampuh lainnya untuk mencapai polimorfisme, terutama saat bekerja dengan class yang tidak saling terkait tetapi memiliki perilaku yang sama.

Dengan interface, polimorfisme berasal dari kontraknya sendiri. Setiap class yang mengimplementasikan interface menjamin bahwa class tersebut memiliki method tertentu, terlepas dari hierarki pewarisannya:

<?php
interface Notifiable {
    public function send(string $message);
}

class EmailNotifier implements Notifiable {
    public function send(string $message) {
        return "Email: " . $message;
    }
}

class SMSNotifier implements Notifiable {
    public function send(string $message) {
        return "SMS: " . $message;
    }
}

class PushNotifier implements Notifiable {
    public function send(string $message) {
        return "Push: " . $message;
    }
}

function notify(Notifiable $notifier, string $message) {
    return $notifier->send($message);
}

echo notify(new EmailNotifier(), "Hello") . "\n";
echo notify(new SMSNotifier(), "Hello") . "\n";
echo notify(new PushNotifier(), "Hello");

Output:

Email: Hello
SMS: Hello
Push: Hello

Fungsi notify() berfungsi dengan object Notifiable apa pun. Class-class ini tidak memiliki class induk yang sama, mereka sepenuhnya tidak berhubungan kecuali karena mengimplementasikan interface yang sama. Inilah keunggulan utama dibandingkan polimorfisme berbasis pewarisan: kamu dapat mengelompokkan class-class yang tidak berhubungan berdasarkan kemampuannya, bukan berdasarkan garis keturunannya.

Poin Penting: Polimorfisme berbasis interface memungkinkan class yang tidak berkaitan digunakan secara bergantian berdasarkan perilaku yang sama, sehingga kodemu lebih fleksibel dan tidak bergantung pada implementasi tertentu.

challenge icon

Tantangan

Mudah

Mari kita bangun sistem penyimpanan yang menunjukkan polimorfisme berbasis interface. Kamu akan membuat backend penyimpanan yang berbeda, yaitu sistem file dan database, yang tidak memiliki kesamaan selain keduanya mengimplementasikan interface penyimpanan yang sama. Satu fungsi akan bekerja dengan tipe penyimpanan apa pun, menunjukkan cara interface memungkinkan polimorfisme antara class yang sama sekali tidak terkait.

Kamu akan mengatur kodemu dalam empat file:

  • Storable.php: Definisikan interface Storable dengan dua deklarasi method: save($key, $data) dan retrieve($key). Kontrak ini memastikan sistem penyimpanan apa pun dapat menyimpan dan mengambil data, terlepas dari cara sistem tersebut diimplementasikan secara internal.
  • FileStorage.php: Buat class FileStorage yang mengimplementasikan Storable. Sertakan file interface. Class ini harus memiliki property privat $directory yang diatur melalui constructor. Implementasikan save($key, $data) agar mengembalikan "Saving '[data]' to file [directory]/[key].txt". Implementasikan retrieve($key) agar mengembalikan "Reading from file [directory]/[key].txt".
  • DatabaseStorage.php: Buat class DatabaseStorage yang juga mengimplementasikan Storable. Sertakan file interface. Class ini harus memiliki property privat $tableName yang diatur melalui constructor. Implementasikan save($key, $data) agar mengembalikan "Inserting '[data]' into table [tableName] with key [key]". Implementasikan retrieve($key) agar mengembalikan "Selecting from table [tableName] where key = [key]".
  • main.php: Sertakan kedua file penyimpanan. Buat fungsi bernama storeData yang menerima parameter bertipe Storable, sebuah kunci, dan data. Fungsi tersebut harus mengembalikan hasil pemanggilan save() dengan kunci dan data. Buat fungsi lain bernama fetchData yang menerima parameter bertipe Storable dan sebuah kunci, lalu mengembalikan hasil pemanggilan retrieve().

Kamu akan menerima empat input: jalur direktori, nama tabel, sebuah kunci, dan data untuk disimpan. Buat FileStorage dengan direktori tersebut dan DatabaseStorage dengan nama tabel tersebut. Gunakan fungsi storeData() untuk menyimpan data, pertama dengan penyimpanan file, lalu dengan penyimpanan database. Cetak setiap hasil pada barisnya sendiri. Lalu gunakan fetchData() untuk mengambil data dari penyimpanan file dan cetak hasilnya.

Perhatikan bahwa storeData() dan fetchData() bekerja dengan cara yang sama pada kedua tipe penyimpanan. Keduanya hanya peduli bahwa object mengimplementasikan Storable. Sistem file dan database memiliki implementasi internal yang sama sekali berbeda, tetapi keduanya dapat saling menggantikan melalui kontrak interface.

Coba sendiri

<?php
require_once 'FileStorage.php';
require_once 'DatabaseStorage.php';

// Baca input
$directory = trim(fgets(STDIN));
$tableName = trim(fgets(STDIN));
$key = trim(fgets(STDIN));
$data = trim(fgets(STDIN));

// TODO: Buat fungsi storeData yang menerima Storable, key, dan data
// Fungsi ini harus mengembalikan hasil pemanggilan save() dengan key dan data

// TODO: Buat fungsi fetchData yang menerima Storable dan key
// Fungsi ini harus mengembalikan hasil pemanggilan retrieve() dengan key

// TODO: Buat instance FileStorage dengan direktori tersebut

// TODO: Buat instance DatabaseStorage dengan nama tabel tersebut

// TODO: Gunakan storeData() untuk menyimpan data ke file, lalu cetak hasilnya

// TODO: Gunakan storeData() untuk menyimpan data ke database, lalu cetak hasilnya

// TODO: Gunakan fetchData() untuk mengambil data dari file, lalu cetak hasilnya
?>
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler PHP online