Yanıtlar:
Geç Statik Bağlamaları mutlaka okumalısınız PHP kılavuzunda . Ancak, size kısa bir özet vermeye çalışacağım.
Temel olarak, self
anahtar kelimenin aynı miras kurallarına uymadığı gerçeğine dayanır . self
her zaman kullanıldığı sınıfa gider. Bu, üst sınıfta bir yöntem yapar ve bunu alt sınıftan çağırırsanız self
, çocuğa beklediğiniz gibi başvurmayacağı anlamına gelir.
Geç statik bağlama, static
anahtar kelime için bu özel eksikliği gideren yeni bir kullanım sağlar . Kullandığınızda static
, ilk kullandığınız sınıfı, yani temsil eder. çalışma zamanı sınıfına 'bağlanır'.
Bunlar arkasındaki iki temel kavram. Yolu self
, parent
ve static
ne zaman işletmek static
daha detaylara yer ince, bu yüzden ziyade gitmek olabilir oyunda, şiddetle manuel sayfa örneklerini incelemek öneriyoruz. Her bir anahtar kelimenin temellerini anladıktan sonra, ne tür sonuçlar elde edeceğinizi görmek için örnekler oldukça gereklidir.
self
anahtar kelime miras kurallarına uymuyor. self
her zaman kullanıldığı sınıfa gider.” - Bu self
, tıpkı statik olmayan yöntemlerde olduğu gibi, bir üst nesneden ebeveynin statik yöntemini çağıramayacağınız anlamına gelmez . Belki de doğru olanı kastediyorsun, ama bunu yeniden ifade etmelisin. Her şey ancak çocuklar aynı adlı üyelere sahip olduklarında gerçekten önemlidir, çünkü static::
bunun yerine hangilerine başvuracağınıza karar verebilirsiniz .
Gönderen PHP: Duruk - Manuel :
PHP 5.3.0'dan itibaren PHP, statik miras bağlamında çağrılan sınıfa başvurmak için kullanılabilen geç statik bağlanma adı verilen bir özellik uygular.
Geç statik bağlama, başlangıçta çalışma zamanında çağrılan sınıfa başvuran bir anahtar sözcük girerek bu sınırlamayı çözmeye çalışır. ... Yeni bir anahtar kelime getirmemeye
static
, daha önce ayrılmış olan anahtar kelimeyi kullanmaya karar verildi.
Bir örnek görelim:
<?php
class Car
{
public static function run()
{
return static::getName();
}
private static function getName()
{
return 'Car';
}
}
class Toyota extends Car
{
public static function getName()
{
return 'Toyota';
}
}
echo Car::run(); // Output: Car
echo Toyota::run(); // Output: Toyota
?>
Geç statik bağlamalar, son "yönlendirme olmayan çağrıda" adı verilen sınıfı saklayarak çalışır. Statik yöntem çağrıları durumunda, bu açıkça adlandırılan sınıftır (genellikle
::
operatörün solundaki sınıftır ); statik olmayan yöntem çağrıları durumunda, nesnenin sınıfıdır. Bir "yönlendirme çağrısı" ile tanıtıldı statik biridirself::
,parent::
,static::
, veya, sınıf hiyerarşisinde yukarıya gidiş eğerforward_static_call()
. İşlevget_called_class()
, çağrılan sınıfın adıyla bir dize almakstatic::
ve kapsamını tanıtmak için kullanılabilir.
Çok açık bir davranış yoktur:
Aşağıdaki kod 'alphabeta' üretir.
class alpha {
function classname(){
return __CLASS__;
}
function selfname(){
return self::classname();
}
function staticname(){
return static::classname();
}
}
class beta extends alpha {
function classname(){
return __CLASS__;
}
}
$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta
Ancak, sınıf adı işlevinin bildirimini beta sınıfından kaldırırsak, sonuç olarak 'alphaalpha' alırız.
Ben kitaptan alıntı yapıyorum: "PHP Master son teknoloji kod yazmak".
Geç statik bağlanma php 5.3 ile sunulan bir özellikti. Statik yöntemleri bir üst sınıftan miras almamıza ve çağrılan alt sınıfı referans göstermemize izin verir.
Bu, statik yöntemlerle soyut bir sınıfa sahip olabileceğiniz ve self :: method () yerine static :: method () gösterimini kullanarak alt sınıfın somut uygulamalarına başvurabileceğiniz anlamına gelir .
Resmi php belgelerine de göz atabilirsiniz: http://php.net/manual/en/language.oop5.late-static-bindings.php
Geç Statik Bağlamayı açıklamanın en açık yolu basit bir örnektir. Aşağıdaki iki sınıf tanımına bir göz atın ve okumaya devam edin.
class Vehicle {
public static function invokeDriveByStatic() {
return static::drive(); // Late Static Binding
}
public static function invokeStopBySelf() {
return self::stop(); // NOT Late Static Binding
}
private static function drive(){
return "I'm driving a VEHICLE";
}
private static function stop(){
return "I'm stopping a VEHICLE";
}
}
class Car extends Vehicle {
protected static function drive(){
return "I'm driving a CAR";
}
private static function stop(){
return "I'm stopping a CAR";
}
}
Bir Ebeveyn Sınıfı (Araç) ve bir Çocuk Sınıfı (Araba) görüyoruz. Ana Sınıfın 2 genel yöntemi vardır:
invokeDriveByStatic
invokeStopBySelf
Ana Sınıfın ayrıca 2 özel yöntemi vardır:
drive
stop
Child Sınıfı 2 yöntemi geçersiz kılar:
drive
stop
Şimdi genel yöntemleri çağıralım:
invokeDriveByStatic
invokeStopBySelf
Kendinize sorun: Hangi sınıf invokeDriveByStatic
/invokeStopBySelf
? Ebeveyn mi, Çocuk sınıfı mı?
Aşağıya bir göz atın:
// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a VEHICLE
echo Vehicle::invokeStopBySelf(); // I'm stopping a VEHICLE
// !!! This is Late Static Binding !!!!
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR
// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a VEHICLE
static
Anahtar kelime bir Singleton tasarım deseni kullanılmıştır. Bkz. Bağlantı: https://refactoring.guru/design-patterns/singleton/php/example
Farkı göstermenin en basit örneği.
Not, kendini :: $ c
class A
{
static $c = 7;
public static function getVal()
{
return self::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 7
Geç statik bağlama, not statik :: $ c
class A
{
static $c = 7;
public static function getVal()
{
return static::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 8
Ayrıca, alt sınıflarda statik değişkenleri güncelleyip güncellemediğinizi de izleyin. Çocuk B'nin çocuk C'yi güncellediği bu (biraz) beklenmedik sonucu buldum:
class A{
protected static $things;
}
class B extends A {
public static function things(){
static::$things[1] = 'Thing B';
return static::$things;
}
}
class C extends A{
public static function things(){
static::$things[2] = 'Thing C';
return static::$things;
}
}
print_r(C::things());
// Array (
// [2] => Thing C
// )
B::things();
print_r(C::things());
// Array (
// [2] => Thing C
// [1] => Thing B
// )
Her alt sınıfta aynı değişkeni bildirerek düzeltebilirsiniz, örneğin:
class C extends A{
protected static $things; // add this and B will not interfere!
public static function things(){
static::$things[2] = 'Thing C';
return static::$things;
}
}