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

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

<?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 вашего дочернего класса.

Другие вопросы по тегам