Arayüzler ile Çok Biçimlilik
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 34 / 91.
Önceki derste, alt sınıfların üst sınıf metotlarını geçersiz kıldığı (override ettiği) kalıtım yoluyla polimorfizmi gördünüz. Arayüzler, özellikle ortak davranışları paylaşan ilişkisiz sınıflarla çalışırken polimorfizm elde etmek için başka bir güçlü yol sunar.
Arayüzler ile polimorfizm sözleşmenin kendisinden gelir. Bir arayüzü uygulayan herhangi bir sınıf, kalıtım hiyerarşisinden bağımsız olarak belirli metotlara sahip olduğunu garanti eder:
<?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");
Çıktı:
Email: Hello
SMS: Hello
Push: Hellonotify() fonksiyonu herhangi bir Notifiable nesnesi ile çalışır. Bu sınıflar bir üst sınıfı paylaşmazlar; aynı arayüzü uygulamaları dışında birbirleriyle tamamen alakasızdırlar. Kalıtım tabanlı polimorfizme karşı temel avantajı şudur: Alakasız sınıfları soylarına göre değil, yeteneklerine göre gruplandırabilirsiniz.
Önemli Nokta: Arayüz tabanlı polimorfizm, ilişkisiz sınıfların paylaşılan davranışlara dayalı olarak birbirinin yerine kullanılabilmesini sağlayarak kodunuzu daha esnek hale getirir ve belirli uygulamalardan ayrıştırır.
Görev
KolayArayüz tabanlı polimorfizmi (çok biçimlilik) gösteren bir depolama sistemi inşa edelim. Aynı depolama arayüzünü uygulamaları dışında birbirleriyle hiçbir ortak noktası olmayan farklı depolama arka uçları —bir dosya sistemi ve bir veritabanı— oluşturacaksınız. Tek bir fonksiyon, herhangi bir depolama türüyle çalışarak arayüzlerin tamamen alakasız sınıflar arasında polimorfizmi nasıl sağladığını sergileyecek.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Storable.php— İki metot imzasına sahip birStorablearayüzü tanımlayın:save($key, $data)veretrieve($key). Bu sözleşme, dahili olarak nasıl uygulandığına bakılmaksızın herhangi bir depolama sisteminin verileri depolayabilmesini ve geri alabilmesini sağlar.FileStorage.php—Storablearayüzünü uygulayan birFileStoragesınıfı oluşturun. Arayüz dosyasını dahil edin. Sınıf, yapıcı (constructor) aracılığıyla ayarlanan özel bir$directoryözelliğine sahip olmalıdır.save($key, $data)metodunu"Saving '$data' to file $this->directory/$key.txt"döndürecek şekilde uygulayın.retrieve($key)metodunu"Reading from file $this->directory/$key.txt"döndürecek şekilde uygulayın.DatabaseStorage.php— YineStorablearayüzünü uygulayan birDatabaseStoragesınıfı oluşturun. Arayüz dosyasını dahil edin. Sınıf, yapıcı aracılığıyla ayarlanan özel bir$tableNameözelliğine sahip olmalıdır.save($key, $data)metodunu"Inserting '$data' into table $this->tableName with key $key"döndürecek şekilde uygulayın.retrieve($key)metodunu"Selecting from table $this->tableName where key = $key"döndürecek şekilde uygulayın.main.php— Her iki depolama dosyasını da dahil edin. BirStorableparametresi, bir anahtar ve veri kabul edenstoreDataadında bir fonksiyon oluşturun. Fonksiyon, anahtar ve veri ilesave()metodunu çağırmanın sonucunu döndürmelidir. BirStorableparametresi ve bir anahtar kabul eden,retrieve()metodunu çağırmanın sonucunu döndürenfetchDataadında başka bir fonksiyon oluşturun.
Dört girdi alacaksınız: bir dizin yolu, bir tablo adı, bir anahtar ve depolanacak bazı veriler. Dizin ile bir FileStorage ve tablo adı ile bir DatabaseStorage oluşturun. Verileri önce dosya depolamasını, ardından veritabanı depolamasını kullanarak kaydetmek için storeData() fonksiyonunuzu kullanın. Her sonucu kendi satırında yazdırın. Ardından dosya depolamasından veri çekmek için fetchData() fonksiyonunu kullanın ve bu sonucu yazdırın.
storeData() ve fetchData() fonksiyonlarının her iki depolama türüyle de nasıl aynı şekilde çalıştığına dikkat edin — onlar sadece nesnenin Storable arayüzünü uygulayıp uygulamadığıyla ilgilenirler. Dosya sistemi ve veritabanı tamamen farklı dahili uygulamalara sahiptir, ancak arayüz sözleşmesi aracılığıyla birbirlerinin yerine kullanılabilirler.
Kopya kağıdı
Arayüzler (Interfaces), ilgisiz sınıfların kalıtım hiyerarşisinden ziyade paylaşılan davranışlara dayalı olarak birbirinin yerine kullanılmasına izin vererek polimorfizmi (çok biçimliliği) sağlar.
Bir arayüzü uygulayan herhangi bir sınıf, belirli metotlara sahip olduğunu garanti ederek polimorfik davranışı mümkün kılan bir sözleşme oluşturur:
<?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;
}
}
function notify(Notifiable $notifier, string $message) {
return $notifier->send($message);
}
echo notify(new EmailNotifier(), "Hello");
echo notify(new SMSNotifier(), "Hello");notify() fonksiyonu, sınıf hiyerarşisinden bağımsız olarak Notifiable arayüzünü uygulayan herhangi bir nesneyi kabul eder. Bu, kodu daha esnek hale getirir ve belirli uygulamalardan bağımsızlaştırır.
Temel avantaj: Arayüz tabanlı polimorfizm, ilgisiz sınıfları soylarına göre değil, yeteneklerine göre gruplandırarak tamamen farklı uygulamaların ortak bir sözleşme aracılığıyla birbirinin yerine kullanılmasına olanak tanır.
Kendin dene
<?php
require_once 'FileStorage.php';
require_once 'DatabaseStorage.php';
// Girdileri oku
$directory = trim(fgets(STDIN));
$tableName = trim(fgets(STDIN));
$key = trim(fgets(STDIN));
$data = trim(fgets(STDIN));
// TODO: Bir Storable, anahtar (key) ve veri (data) kabul eden bir storeData fonksiyonu oluşturun
// Bu fonksiyon, anahtar ve veri ile save() metodunu çağırmanın sonucunu döndürmelidir
// TODO: Bir Storable ve anahtar (key) kabul eden bir fetchData fonksiyonu oluşturun
// Bu fonksiyon, anahtar ile retrieve() metodunu çağırmanın sonucunu döndürmelidir
// TODO: Dizin (directory) ile bir FileStorage örneği oluşturun
// TODO: Tablo adı (table name) ile bir DatabaseStorage örneği oluşturun
// TODO: Dosya depolama ile veriyi kaydetmek için storeData() kullanın, ardından sonucu yazdırın
// TODO: Veritabanı depolama ile veriyi kaydetmek için storeData() kullanın, ardından sonucu yazdırın
// TODO: Dosya depolamadan veri getirmek için fetchData() kullanın, ardından sonucu yazdırın
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi