Geç Bağlanan Statik Çağrılar
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 36 / 91.
Bir üst sınıfta self:: kullandığınızda, bu her zaman gerçekten kullanılan sınıfa değil, yazıldığı sınıfa başvurur. Bu, kalıtımda beklenmedik davranışlara yol açabilir. Geç bağlanan statik çağrılar, bu sorunu static:: anahtar sözcüğünü kullanarak çözer.
self:: ifadesinin beklendiği gibi çalışmadığı şu örneği inceleyin:
<?php
class ParentClass {
public static function create() {
return new self();
}
public static function getClassName() {
return self::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
Çıktı:
ParentClass
ParentClassChildClass::create() çağırmış olmamıza rağmen, ParentClass nesnesi elde ettik; çünkü self:: derleme zamanında çözümlenir. Şimdi bunun yerine static:: kullanalım:
<?php
class ParentClass {
public static function create() {
return new static();
}
public static function getClassName() {
return static::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
Çıktı:
ChildClass
ChildClassstatic:: ile PHP, hangi sınıfın kullanılacağını belirlemek için çalışma zamanını bekler. Karar ertelendiği için buna "geç" bağlama denir. Bu, fabrika metotları ve kalıtıma uyması gereken tüm statik metotlar için gereklidir.
Temel Nokta: Alt sınıfların statik davranışı düzgün şekilde devralmasını ve özelleştirmesini istediğinde self:: yerine static:: kullan.
Görev
KolayGeç statik bağlamanın gücünü gösteren bir model kayıt sistemi oluşturalım. Alt sınıfların devralabileceği bir fabrika metoduna sahip temel bir Model sınıfı oluşturacaksın ve static:: sayesinde her alt sınıf, üst sınıf yerine doğru şekilde kendisinin örneklerini oluşturacak.
Kodunu dört dosyaya ayıracaksın:
Model.php:"models"olarak ayarlanmış, korumalı bir statik$tableNameözelliğine sahip temel birModelsınıfı oluştur. Yeni bir örnek döndürmek içinnew static()kullanan ve kendisini çağıran sınıf ne olursa olsun onun yeni bir örneğini döndüren statik bircreate()metodu ekle.static::$tableNamedöndüren başka bir statikgetTable()metodu ekle. Son olarak,static::classvestatic::$tableNamekullanarak"[ClassName] from table [tableName]"döndüren birdescribe()metodu ekle.User.php:Modelsınıfını genişleten birUsersınıfı oluştur. Üst sınıf dosyasını dahil et. Statik$tableNameözelliğini"users"olarak geçersiz kıl. Sınıf,Modelsınıfındaki tüm metotları herhangi bir değişiklik olmadan devralır.Product.php:Modelsınıfını genişleten birProductsınıfı oluştur. Üst sınıf dosyasını dahil et. Statik$tableNameözelliğini"products"olarak geçersiz kıl. Sınıf, üst sınıftaki tüm metotları yine devralır.main.php: Hem User hem de Product dosyalarını dahil et. HemUserhem deProductörnekleri oluşturmak için devralınancreate()fabrika metodunu kullan. Her örnek içindescribe()metodunu çağır ve sonucu kendi satırına yazdır. ArdındanUser::getTable()veProduct::getTable()kullanarak her sınıfın tablo adını yazdır; her birini kendi satırına yazdır.
Buradaki sihir, create() ve getTable() metotlarının yalnızca üst sınıf olan Model içinde tanımlanmış olmasına rağmen, static:: bağlamayı çalışma zamanına kadar ertelediği için alt sınıflarla doğru şekilde çalışmasıdır. User::create() çağrıldığında PHP, Model örneği değil, bir User örneği oluşturur; çünkü static::, gerçekten çağrılan sınıfa başvurur.
Çıktın dört satır göstermelidir: User örneğinin açıklaması, Product örneğinin açıklaması, User tablo adı ve Product tablo adı.
Kendin dene
<?php
require_once 'User.php';
require_once 'Product.php';
// TODO: Bir User örneği oluşturmak için miras alınan create() fabrika metodunu kullan
// TODO: Bir Product örneği oluşturmak için miras alınan create() fabrika metodunu kullan
// TODO: User örneğinde describe() metodunu çağır ve sonucu yazdır
// TODO: Product örneğinde describe() metodunu çağır ve sonucu yazdır
// TODO: User::getTable() yazdır
// TODO: Product::getTable() yazdır
?>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 SözcüğüMetotlarÖzelliklerYapıcı (__construct)Yıkıcı (__destruct)Tekrar - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar SözcüğüMetot Geçersiz Kılmafinal Anahtar SözcüğüSoyut SınıflarTekrar - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicileri DerinlemesineGetter ve Setter'larBilgi GizlemeYapıcı Özellik Terfisi (8.0)Tekrar - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Composition ve KalıtımBağımlılık EnjeksiyonuAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlamaya Derinlemesine BakışÜreteçler ve Yineleyiciler13Tasarı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ıBileşik KalıpDepo Kalıbı2Namespace’ler ve Autoloading
Namespace’lere Girişuse Anahtar SözcüğüPSR-4 Autoloading StandardıComposer AutoloaderTekrar - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Çok Arayüz UygulamaArayüz ve Soyut Sınıf KarşılaştırmasıArayüzlerle Tür İpuçlarıTekrar - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString ve __debugInfo__get, __set, __isset, __unset__call ve __callStatic__clone ve Nesne Klonlama__serialize ve __unserializeTekrar - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerSalt Okunur Özellikler (PHP 8.1)Tekrar - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmayı Yeniden Ele AlmaArayüzler Yoluyla Çok BiçimlilikTür İpuçları ve Birleşim TürleriGeç Bağlanan Statik ÇağrılarÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişBirden Çok Trait KullanımıTrait Çakışmalarını ÇözümlemeTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım Karşılaştırması12Tasarım Desenleri 1. Bölüm
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online PHP derleyicisi