Arayüz vs Soyut Sınıf
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 30 / 91.
Hem arayüzleri hem de soyut sınıfları öğrendiğinize göre, her birini ne zaman kullanacağımızı netleştirelim. Benzer görünseler de, farklı amaçlara hizmet ederler ve belirgin yeteneklere sahiptirler.
| Özellik | Interface (Arayüz) | Abstract Class (Soyut Sınıf) |
|---|---|---|
| Metotlar | Sadece metot imzaları | Hem soyut hem de somut metotlar |
| Özellikler (Properties) | Sadece sabitler | Özelliklere sahip olabilir |
| Çoklu kalıtım | Bir sınıf birden fazlasını uygulayabilir (implement) | Bir sınıf sadece birini genişletebilir (extend) |
| Yapıcı Metot (Constructor) | İzin verilmez | Yapıcı metoda sahip olabilir |
Birbiriyle ilişkisi olmayan sınıfların yerine getirebileceği bir sözleşme tanımlamak istediğinizde bir arayüz kullanın. Örneğin, ortak bir ataya sahip olmasalar bile hem bir Printer hem de bir Logger, bir Writable arayüzünü uygulayabilir.
Ortak kod paylaşan ilişkili sınıflarınız olduğunda bir soyut sınıf (abstract class) kullanın. Eğer Dog ve Cat sınıflarınızın her ikisi de aynı eat() metot uygulamasına ihtiyaç duyuyorsa, soyut bir Animal sınıfı bu kodu bir kez yazmanıza olanak tanır.
Her iki yaklaşımı da birleştirebilirsiniz. Bir sınıf, birden fazla arayüzü uygularken bir soyut sınıfı genişletebilir:
<?php
abstract class Animal {
protected $name;
public function eat() {
return $this->name . " is eating";
}
}
interface Swimmable {
public function swim();
}
class Duck extends Animal implements Swimmable {
public function __construct($name) {
$this->name = $name;
}
public function swim() {
return $this->name . " is swimming";
}
}
Önemli Nokta: Birbiriyle ilişkisi olmayan sınıflar genelinde yetenekleri tanımlamak için arayüzleri (interfaces) tercih edin. İlişkili sınıflar arasında kod paylaşmanız gerektiğinde soyut sınıfları (abstract classes) tercih edin.
Görev
KolaySoyut bir sınıfın ne zaman kullanılacağını, bir arayüzün (interface) ne zaman kullanılacağını ve her iki yaklaşımın nasıl etkili bir şekilde birleştirileceğini gösteren bir araç sistemi oluşturalım.
Araçların ortak özellikleri kalıtım yoluyla paylaştığı, ancak arayüzler aracılığıyla ek yetenekler kazanabildiği bir sistem oluşturacaksınız. Bu, gerçek dünyadaki tasarım kararlarını yansıtır: bir araba bir araçtır ("is a" - kalıtım), ancak aynı zamanda yakıt doldurulabilir olma ("has the capability" - arayüz) yeteneğine de sahiptir.
Kodunuzu dört dosya halinde düzenleyin:
Refuelable.php— Tek bir metot imzasına sahip birRefuelablearayüzü tanımlayın:refuel($amount). Bu yetenek, kalıtım hiyerarşisinden bağımsız olarak yakıt ikmali gerektiren herhangi bir sınıfa uygulanabilir.Vehicle.php— Tüm araçlar için paylaşılan işlevsellik sağlayan soyut birVehiclesınıfı tanımlayın. Korumalı (protected) bir$brandözelliğine ve korumalı bir$fuelLevelözelliğine (0'dan başlayan) sahip olmalıdır. Yapıcı metot (constructor) marka adını kabul eder. Markayı döndüren somut birgetBrand()metodu, mevcut yakıt seviyesini döndüren somut birgetFuelLevel()metodu ve alt sınıfların uygulaması gereken soyut birdrive()metodu ekleyin.Car.php—Vehiclesınıfını genişleten veRefuelablearayüzünü uygulayan birCarsınıfı oluşturun. Gerekli her iki dosyayı da en üste dahil edin. Yapıcı metot markayı kabul eder ve bunu üst sınıf yapıcısına iletir.drive()metodunu"[brand] car is driving"döndürecek şekilde uygulayın.refuel($amount)metodunu, miktarı yakıt seviyesine ekleyecek ve"[brand] refueled to [fuelLevel] liters"döndürecek şekilde uygulayın.main.php— Car dosyasını dahil edin. İki girdi alacaksınız: bir marka adı ve bir yakıt miktarı (tam sayıya dönüştürün). Marka ile birCarnesnesi oluşturun. İlk satıradrive()sonucunu yazdırın, ardından ikinci satıra yakıt miktarı ilerefuel()sonucunu yazdırın.
Bu görev temel ayrımı göstermektedir: soyut Vehicle sınıfı kodu paylaşır ve bir "is-a" (bir ...-dır) ilişkisi kurar; Refuelable arayüzü ise araç olmalarını gerektirmeden diğer ilgisiz sınıflara (jeneratör veya tekne gibi) uygulanabilecek bir yetenek ekler.
Kopya kağıdı
Arayüzler ve soyut sınıflar farklı amaçlara hizmet eder:
| Özellik | Arayüz (Interface) | Soyut Sınıf (Abstract Class) |
|---|---|---|
| Metotlar | Yalnızca metot imzaları | Hem soyut hem de somut metotlar |
| Özellikler (Properties) | Yalnızca sabitler | Özelliklere sahip olabilir |
| Çoklu kalıtım | Bir sınıf birden fazlasını uygulayabilir | Bir sınıf yalnızca birini genişletebilir |
| Yapıcı Metot (Constructor) | İzin verilmez | Yapıcı metoda sahip olabilir |
İlişkisiz sınıflar için bir sözleşme tanımlamak üzere bir arayüz (interface) kullanın. İlgili sınıflar arasında ortak kod paylaşmak için bir soyut sınıf (abstract class) kullanın.
Bir sınıf, birden fazla arayüzü uygularken aynı zamanda bir soyut sınıfı genişletebilir:
<?php
abstract class Animal {
protected $name;
public function eat() {
return $this->name . " is eating";
}
}
interface Swimmable {
public function swim();
}
class Duck extends Animal implements Swimmable {
public function __construct($name) {
$this->name = $name;
}
public function swim() {
return $this->name . " is swimming";
}
}
Kendin dene
<?php
require_once 'Car.php';
// Girdiyi oku
$brand = trim(fgets(STDIN));
$fuelAmount = intval(trim(fgets(STDIN)));
// YAPILACAK: Marka ile bir Araba (Car) oluşturun
// YAPILACAK: İlk satıra drive() sonucunu yazdırın
// YAPILACAK: İkinci satıra yakıt miktarı ile refuel() sonucunu 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