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: HelloFungsi 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.
Tantangan
MudahMari 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 interfaceStorabledengan dua deklarasi method:save($key, $data)danretrieve($key). Kontrak ini memastikan sistem penyimpanan apa pun dapat menyimpan dan mengambil data, terlepas dari cara sistem tersebut diimplementasikan secara internal.FileStorage.php: Buat classFileStorageyang mengimplementasikanStorable. Sertakan file interface. Class ini harus memiliki property privat$directoryyang diatur melalui constructor. Implementasikansave($key, $data)agar mengembalikan"Saving '[data]' to file [directory]/[key].txt". Implementasikanretrieve($key)agar mengembalikan"Reading from file [directory]/[key].txt".DatabaseStorage.php: Buat classDatabaseStorageyang juga mengimplementasikanStorable. Sertakan file interface. Class ini harus memiliki property privat$tableNameyang diatur melalui constructor. Implementasikansave($key, $data)agar mengembalikan"Inserting '[data]' into table [tableName] with key [key]". Implementasikanretrieve($key)agar mengembalikan"Selecting from table [tableName] where key = [key]".main.php: Sertakan kedua file penyimpanan. Buat fungsi bernamastoreDatayang menerima parameter bertipeStorable, sebuah kunci, dan data. Fungsi tersebut harus mengembalikan hasil pemanggilansave()dengan kunci dan data. Buat fungsi lain bernamafetchDatayang menerima parameter bertipeStorabledan sebuah kunci, lalu mengembalikan hasil pemanggilanretrieve().
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
?>Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengenalan OOPclass vs objectKata Kunci $thismethodpropertyConstructor (__construct)Destructor (__destruct)Ringkasan: Kalkulator Sederhana4Pewarisan
Pewarisan DasarKata Kunci parent::Penimpaan methodKata Kunci finalClass AbstrakRingkasan: Hierarki Karyawan7Enkapsulasi
Public, Protected, PrivateModifier Akses secara MendalamGetter dan SetterPenyembunyian InformasiPromosi Constructor (8.0)Ulasan: Sistem Catatan Siswa2Namespace dan Autoloading
Pengenalan NamespaceKata Kunci useStandar Autoloading PSR-4Autoloader ComposerRingkasan: Proyek yang Terorganisasi5Interface dan Kontrak
Pengenalan InterfaceMengimplementasikan InterfaceImplementasi Beberapa InterfaceInterface vs Abstract ClassPetunjuk Tipe dengan InterfaceRekap: Kalkulator Bentuk8Magic Methods
Pengantar Magic Methods__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Cloning Object__serialize & __unserializeRingkasan: Koleksi Kustom11Sistem Tipe Data dan Penanganan Error
Deklarasi TipeTipe NullableTipe Union dan IntersectionClass ExceptionHierarki Exception KustomTry, Catch, FinallyRekap: Validator Form3Property dalam class
Property instance vs staticKonstanta dalam classMethod & property staticProperty private & protectedProperty readonly (PHP 8.1)Ulasan: Pengelola Rekening Bank6Polimorfisme
Meninjau Kembali Method OverridingPolimorfisme melalui AntarmukaPetunjuk Tipe dan Tipe UnionPengikatan Statis TertundaRangkuman: Pemroses PembayaranLatihan sendiri: Compiler PHP online