Я хотел бы лучше понять, почему в приведенном ниже сценарии существует разница в способе наследования констант класса и переменных экземпляра.
<?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 (), поэтому метод showTest () ParentClass используется по наследству. Результаты показывают, что, поскольку метод выполняется в ParentClass, оценивается версия ParentClass константы TEST, тогда как, поскольку она оценивается в контексте ChildClass через наследование, оценивается переменная-член ChildClass $ test.
Я прочитал документацию, но, похоже, не вижу упоминания об этом нюансе. Может ли кто-нибудь пролить свет на меня?
php
oop
inheritance
overriding
constants
Том Аугер
источник
источник
final
...Ответы:
self::
Не учитывает наследование и всегда относится к классу, в котором выполняется. Если вы используете php5.3 +, вы можете попробовать,static::TEST
посколькуstatic::
он поддерживает наследование.Разница в том, что
static::
используется «позднее статическое связывание». Более подробную информацию можно найти здесь:http://php.net/manual/en/language.oop5.late-static-bindings.php
Вот простой тестовый сценарий, который я написал:
вывод
источник
static::
.test()
это не статический метод, почему бы не использовать его$this::TEST
с PHP5.3 +?self::
/,static::
но не понимаю, зачем использоватьstatic::
вместо$this::
(нетself::
). Есть ли разница между$this::
иstatic::
(поскольку есть разница междуstatic::
/$this::
иself::
)?В PHP self относится к классу, в котором определен вызываемый метод или свойство. Так что в вашем случае вы звоните
self
вChildClass
, поэтому он использует переменную из этого класса. Затем вы используетеself
inParentClass
, поэтому он будет ссылаться на переменную в этом классе.если вы все еще хотите, чтобы дочерний класс переопределил
const
родительский класс, настройте следующий код в родительском классе на это:Обратите внимание на
static
ключевое слово. Здесь используется «позднее статическое связывание». Теперь ваш родительский класс будет вызывать const вашего дочернего класса.источник