PHP statik sınıflarını genişletme

3 Cevap php

Ben şimdi gün boyunca bu alanda mücadele ettik ve ben bir sonuca ulaşmış, ancak sonuç pes önce ben, ne arıyordu değildi çünkü, ben diğer insanların ne söylediklerini görmek için çalışacağım. İnanç son ölür ...

Kullanıcının biz ("Super" olarak adlandırılır) bir üst sınıfı ve ("Alt" olarak adlandırılır) bir alt sınıfı var diyelim.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo self::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

Sub Süper, Sub şimdi Super metodlarının bütün miras, ancak sadece Sub yöntemlerine başvurularını almak gibi görünüyor uzanır yana Şimdi, muhtemelen beklenebilir.

Ben ararım çünkü eğer bu demek:

Sub::get_class_name();

çıktı "Alt", "Süper" ve değildir.

Ve ben diyebilir:

Sub::get_title();

yine çıktı "süper", ve hatta $ başlık Sub ilan var.

Yani bu, ben bir miras statik işlevini çağırdığınızda, işlevin kapsamı süper sınıfı, çağırdı bir (Eğer geri izleme yazdırmak bile, çağrı üst sınıftan yapılmış olduğunu göstereceğim!) Olacağı anlamına gelir ve çağrı üzerine yapılıyor alt sınıfı olarak kapsamını elde etmek için, o alt sınıfın içinde bu yöntemi redeclare gerekir. Well this kind of defeats the purpose of extending classes, don't it?

So my question is, can I ever extend a static class, call one of the inherited methods and have the subclass's scope? or at least to be able to identify it's classname? And if not, why would I ever want to extend static classes?

Teşekkürler!

3 Cevap

Yine, bu önceki PHP 5.3.0 mümkün değildir.

Late Static Binding was introduced in PHP 5.3.0 and allows you to do exactly what you want via the static anahtar kelime.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

get_class_name() Hala olsa __CLASS__ her zaman geçerli sınıf yöntem çalıştırılıyor (tür gibi ilan edilir döndürür etti Super dönecektir __FILE__, hangi olursa olsun her zaman bunu dahil ya da değil) Geçerli dosyayı döndürür.

Bunun için Sub sınıfına yeniden ilan işlevi ancak herhangi bir seçim yok.

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';

    public static function get_class_name()        
    {
        echo __CLASS__;
    }
}

Bunu statik olsa bile, get_called_class() aradığınız sınıfın sınıf adını almak için kullanılabilir. Her yerde ilan etmek zorunda değilsiniz.

Andrew Örnek Gönderen:

class Super {
    public static function get_class1_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo get_called_class();
    }

}
class Sub extends Super {    
    public static function get_class2_name()        
    {
        echo __CLASS__;
    }

}
Sub::get_title(); // Echos Sub.
Sub::get_class1_Name(); // echos super
Sub::get_class2_Name(); // echos sub

Bu nedenle herhangi bir değişken bildirmek zorunda değilsiniz.

Neyse ki, benim için bir şey yapıyorum, bu yüzden dedim, o vida, ben PHP5.3 kullanıyorum. Ama öyle bile olsa, ben belki 10 sınıflar gibi uzatıyorum, her sınıfta "_class _name olsun" redeclare zorunda sevmiyorum. Yani bu çözüm ile geldi:

class Super {
    protected static $classname = __CLASS__;
    public static function get_classname($name)
    {
        static::$classname = $name;
    }
    public static function get_classname()
    {
        return static::$classname;
    }
}
class Sub1 extends Super { }
class Sub2 extends Super { }
class Sub3 extends Super { }

$classes = get_declared_classes();
foreach($classes as $k => $v)
{
    if (is_subclass_of($v, 'Super'))
    {
        $v::set_classname($v);
    }
}

echo Sub1::get_classname(); // Sub1
echo Sub2::get_classname(); // Sub2
echo Sub3::get_classname(); // Sub3

Bu biraz kirli görünebilir, ama ben o kadar da kötü olduğunu düşünmüyorum. Bu işlem ile, nihayet yeniden ilan yöntemleri kalmadan statik yöntemleri uzatabilirsiniz.