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

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

<?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 через наследование, оценивается членная переменная $TestClassClass.

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

Ответ 1

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

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

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

Вот простой тест script Я написал:

<?php

class One
{
    const TEST = "test1";

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

$c = new Two();

$c->test();

Выход

test2

Ответ 2

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

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

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

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