Переопределение констант класса против свойств
Я хотел бы лучше понять, почему в приведенном ниже сценарии существует различие в способе наследования констант класса и переменных экземпляра.
<?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.
Я прочитал документацию, но не вижу упоминания об этом нюансе. Кто-нибудь может пролить немного света на меня?
2 ответа
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
В PHP self относится к классу, в котором определяется вызываемый метод или свойство. Так что в вашем случае вы звоните self
в ChildClass
поэтому он использует переменную из этого класса. Тогда вы используете self
в ParentClass
, поэтому он будет ссылаться на переменную в этом классе.
если вы все еще хотите, чтобы дочерний класс переопределил const
родительского класса, затем настройте следующий код в родительском классе на это:
public function showTest(){
echo static::TEST;
echo $this->test;
}
Обратите внимание static
ключевое слово. Это использует "позднее статическое связывание". Теперь ваш родительский класс будет вызывать const вашего дочернего класса.