it-swarm.com.ru

Переопределение констант класса против свойств

Я хотел бы лучше понять, почему в приведенном ниже сценарии существует различие в способе наследования констант класса и переменных экземпляра.

<?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();

Результат:

TWO
TWO
ONE
TWO

В приведенном выше коде ChildClass не имеет метода showTest (), поэтому метод ParentClass showTest () используется наследованием. Результаты показывают, что, поскольку метод выполняется в ParentClass, оценивается версия константы TEST ParentClass, в то время как она оценивается в контексте ChildClass посредством наследования, оценивается переменная-член ChildClass $ test.

Я прочитал документацию, но не вижу упоминания об этом нюансе. Кто-нибудь может пролить свет на меня?

84
Tom Auger

self:: Не учитывает наследование и всегда ссылается на класс, в котором он выполняется. Если вы используете php5.3 +, вы можете попробовать static::TEST, так как static:: поддерживает наследование.

Разница в том, что static:: использует "позднюю статическую привязку". Найти больше информации здесь:

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

Вот простой тестовый скрипт, который я написал:

<?php

class One
{
    const TEST = "test1";

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

$c = new Two();

$c->test();

Выход

test2
167
David Farrell

В PHP self относится к классу, в котором определяется вызываемый метод или свойство. Итак, в вашем случае вы вызываете self в ChildClass, поэтому он использует переменную из этого класса. Затем вы используете self в ParentClass, поэтому он будет ссылаться на переменную в этом классе.

если вы все еще хотите, чтобы дочерний класс переопределил const родительского класса, то настройте следующий код в родительском классе на это:

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

Обратите внимание на ключевое слово static. Это использует "позднее статическое связывание". Теперь ваш родительский класс будет вызывать const вашего дочернего класса.

13
w00