Sınıf sabitleri vs özelliklerin geçersiz kılınması


99

Aşağıdaki senaryoda, örnek değişkenlere karşı sınıf sabitlerinin miras alınma şekli arasında neden bir fark olduğunu daha iyi anlamak istiyorum.

<?php
class ParentClass {
    const TEST = "ONE";
    protected $test = "ONE";

    public function showTest(){
        echo self::TEST;
        echo $this->test;
    }
}

class ChildClass extends ParentClass {
    const TEST = "TWO";
    protected $test = "TWO";

    public function myTest(){
        echo self::TEST;
        echo $this->test;
    }
}

$child = new ChildClass();
$child->myTest();
$child->showTest();

Çıktı:

TWO
TWO
ONE
TWO

Yukarıdaki kodda, ChildClass bir showTest () yöntemine sahip değildir, bu nedenle miras tarafından ParentClass showTest () yöntemi kullanılır. Sonuçlar, yöntem ParentClass üzerinde yürütüldüğünden, TEST sabitinin ParentClass sürümünün değerlendirildiğini, ancak kalıtım yoluyla ChildClass bağlamında değerlendirildiği için ChildClass üye değişkeni $ testinin değerlendirildiğini göstermektedir.

Belgeleri okudum, ancak bu nüanstan bahsedildiğini göremiyorum. Biri benim için biraz ışık tutabilir mi?


O NE LAN? Sürekli ağır basan !? Bunu yapma! asla!
qwert_ukg

2
@qwert_ukg Gerçekten. Birisi bunu PHP geliştiricilerine iletmelidir. Ya da en azından izin final
ver

1
Sürekli geçersiz kılma için bile yeterince iyi kullanım durumları vardır:]
Arziel

Yanıtlar:


194

self::Kalıtım farkında değildir ve her zaman yürütüldüğü sınıfa atıfta bulunur. Eğer php5.3 + kullanıyorsanız , kalıtım farkındalı static::TESTolarak deneyebilirsiniz static::.

Fark, static::"geç statik bağlama" kullanmasıdır. Daha fazla bilgiyi burada bulabilirsiniz:

http://php.net/manual/en/language.oop5.late-static-bindings.php

İşte yazdığım basit bir test komut dosyası:

<?php

class One
{
    const TEST = "test1";

    function test() { echo static::TEST; }
}
class Two extends One
{
    const TEST = "test2";
}

$c = new Two();

$c->test();

çıktı

test2

22
+ bahsetmek için static::.
Jason McCreary

Harika. Açıklığa kavuşturduğunuz ve geç statik bağlamalar (henüz sindiremediğim) hakkında ek bilgi sağladığınız için teşekkür ederiz.
Tom Auger

3
Yana test()neden kullanmıyor statik yöntem değildir $this::TESTPHP5.3 + ile?
Xenos

Merhaba @Xenos - Örneğin amacı, Birinci sınıfta yürütülen örnek düzeyinde kodun İkinci sınıftan statik değerler aldığını göstermekti. self :: TEST, statik :: TEST'in beklenen "test2" yi döndürdüğü "test1" sonucunu döndürürdü - Umarım yardımcı olur, yanıtladığınız için teşekkürler!
David Farrell

Merhaba @DavidFarrell - Evet, self::/ static::farkını anladım ama (değil ) static::yerine neden kullandığını anlamıyorum . Arasında bir fark var mı ve (aralarında bir tane var çünkü / ve )? $this::self::$this::static::static::$this::self::
Xenos

17

PHP'de self, çağrılan yöntemin veya özelliğin tanımlandığı sınıfı ifade eder. Yani sizin durumda aradığınız selfyılında ChildClassbu sınıftan değişkeni kullanır, böylece. Sonra selfin kullanırsınız ParentClass, böylece o sınıftaki değişkene başvurur.

constAlt sınıfın üst sınıfın değerini yine de geçersiz kılmasını istiyorsanız, üst sınıfınızda aşağıdaki kodu buna ayarlayın:

public function showTest(){
    echo static::TEST;
    echo $this->test;
}

Not staticanahtar kelime. Bu, "geç statik bağlama" kullanır. Artık ebeveyn sınıfınız, çocuk sınıfınızın sabitini arayacak.


pro. statik :: öz yerine soyutlamayla iş yaptı ::
Błażej Krzakala
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.