Почему php позволяет изменять const в подклассах?

Я не понимаю, почему следующий код работает. Разве STEALTH не переопределяется в подклассе... хотя он объявлен как const в родительском? К вашему сведению, у меня сложилось впечатление, что const предотвращает переопределение переменной!

  class Person {
    const STEALTH = "MINIMUM";
  }

  class Ninja extends Person {          
    const STEALTH = "MAXIMUM";
  }

  echo Ninja::STEALTH; // prints out 'MAXIMUM'

Обратите внимание, что я не спрашиваю об операторе разрешения области видимости. Кажется, я понимаю разницу между распечаткой Ninja::STEALTH и Person::STEALTH. Я просто удивлен тем фактом, что ниндзя может наследовать константную переменную и при этом иметь возможность переопределить ее!


person Grateful    schedule 11.07.2017    source источник
comment
Возможный дубликат переопределения констант класса и свойств   -  person mingos    schedule 11.07.2017
comment
Кто сказал, что он переопределен?   -  person u_mulder    schedule 11.07.2017
comment
Person::STEALTH и Ninja::STEALTH явно разные вещи…   -  person deceze♦    schedule 11.07.2017
comment
@deceze Да, я это вижу. Я не спрашиваю об операторе разрешения области видимости. Меня удивляет тот факт, что ниндзя наследует личность и при этом может переопределить STEALTH.   -  person Grateful    schedule 11.07.2017
comment
Здесь нет переопределения. У вас есть две разные константы.   -  person u_mulder    schedule 11.07.2017
comment
@u_mulder Но тогда, если у меня нет этого второго переопределения константы ... и echo Ninja::STEALTH, я смогу распечатать родительское значение MINIMUM? Кажется, что значение наследуется... и если это так, то почему я могу определить НОВУЮ константу с ТАКИМ ЖЕ именем константы, которая уже существует через наследование? Обычно я понимаю переопределение... но в этом случае, как я могу переопределить переменную const?   -  person Grateful    schedule 12.07.2017
comment
Перестаньте думать values, думайте items. У вас есть item типа constant в классе Person. Поскольку класс Ninja наследует класс Person, класс Ninja знает о каждом item (который не является закрытым) родительского класса. Итак, класс Ninja знает о item типа constant. Теперь вы определяете новый item типа constant с тем же именем в классе Ninja. Итак, у вас есть два элемента: один item из родительского класса и второй item в самом Ninja.   -  person u_mulder    schedule 12.07.2017


Ответы (2)


const просто означает, что значение нельзя изменить во время выполнения. Это не ограничивает классы от независимого определения константы с тем же именем; единственное, что правила наследования будут определять, когда и как родительское значение может быть затенено дочерним.

person deceze♦    schedule 11.07.2017

У меня сложилось впечатление, что const предотвращает переопределение переменной!

const предотвращает изменение значения.

Невозможно определить два разных объекта с одинаковым именем, используя define(). . Также невозможно определить два разных объекта с одинаковым именем с помощью const. Доступ к члену класса const всегда осуществляется по его полному имени (имя класса + :: + имя константы).

Имя константы STEALTH, определенной классом Person, — Person::STEALTH. Класс Ninja объявляет константу Ninja::STEALTH.

Это разные объекты.

Свойства класса conststatic) не наследуются так же, как свойства экземпляра. Если свойство const, определенное базовым классом, не маскируется другим объектом с таким же именем, определенным дочерним классом, свойство const базового класса копируется в дочерний класс, и к нему можно получить доступ, используя имя дочернего класса.

Например:

class Person {
    const STEALTH = "MINIMUM";
}

class Citizen extends Person {

}

class Ninja extends Person {          
    const STEALTH = "MAXIMUM";
}

echo Person::STEALTH;    // prints out 'MINIMUM'
echo Citizen::STEALTH;   // prints out 'MINIMUM'; same as Person::STEALTH 
echo Ninja::STEALTH;     // prints out 'MAXIMUM'

Поскольку класс Citizen расширяет класс Person и не определяет собственную константу STEALTH, Citizen::STEALTH является копией Person::STEALTH1.

Константы класса — это глобальные объекты с причудливыми именами (и модификаторами видимости класса, начиная с PHP 7.0).

person axiac    schedule 11.07.2017
comment
Хорошо... теперь это имеет для меня больше смысла! Спасибо! - person Grateful; 11.07.2017
comment
Кажется, const переменные унаследованы. Я закомментировал const STEALTH = "MAXIMUM"; в классе Ninja... и все же смог распечатать Ninja::STEALTH. Он напечатал унаследованное значение MINIMUM.... Я снова запутался! - person Grateful; 12.07.2017
comment
Действительно, к свойствам класса const и static базового класса можно получить доступ из дочернего класса, используя имя дочернего класса. С этой точки зрения они наследуются. Я имел в виду, что Ninja::STEALTH — это тот же объект, что и Person::STEALTH, а не копия. Это проблематично для свойств static (но не так проблематично для const, потому что их нельзя изменить). Думаю, я переформулирую ответ. - person axiac; 12.07.2017