Menu
Coddy logo textTech

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
ParentClass

ChildClass::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
ChildClass

static:: 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.

challenge icon

Görev

Kolay

Geç 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 bir Model sınıfı oluştur. Yeni bir örnek döndürmek için new static() kullanan ve kendisini çağıran sınıf ne olursa olsun onun yeni bir örneğini döndüren statik bir create() metodu ekle. static::$tableName döndüren başka bir statik getTable() metodu ekle. Son olarak, static::class ve static::$tableName kullanarak "[ClassName] from table [tableName]" döndüren bir describe() metodu ekle.
  • User.php: Model sınıfını genişleten bir User sı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, Model sınıfındaki tüm metotları herhangi bir değişiklik olmadan devralır.
  • Product.php: Model sınıfını genişleten bir Product sı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. Hem User hem de Product örnekleri oluşturmak için devralınan create() fabrika metodunu kullan. Her örnek için describe() metodunu çağır ve sonucu kendi satırına yazdır. Ardından User::getTable() ve Product::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

?>
quiz iconKendini test et

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

Kendi başına pratik yap: Online PHP derleyicisi