Абстрактные константы в PHP. Заставьте дочерний класс определить константу

Я заметил, что вы не можете иметь абстрактные константы в PHP.

Есть ли способ заставить дочерний класс определять константу (которую мне нужно использовать в одном из внутренних методов абстрактного класса)?

constantconstant ; по-моему, нет никаких abstract или private констант в PHP, но вы можете работать:

Пример абстрактного класса

 abstract class Hello { const CONSTANT_1 = 'abstract'; // Make Abstract const CONSTANT_2 = 'abstract'; // Make Abstract const CONSTANT_3 = 'Hello World'; // Normal Constant function __construct() { Enforcer::__add(__CLASS__, get_called_class()); } } 

Это будет нормально

 class Foo extends Hello { const CONSTANT_1 = 'HELLO_A'; const CONSTANT_2 = 'HELLO_B'; } new Foo(); 

Бар вернет ошибку

 class Bar extends Hello { const CONSTANT_1 = 'BAR_A'; } new Bar(); 

Сонго вернет ошибку

 class Songo extends Hello { } new Songo(); 

Класс Enforcer

 class Enforcer { public static function __add($class, $c) { $reflection = new ReflectionClass($class); $constantsForced = $reflection->getConstants(); foreach ($constantsForced as $constant => $value) { if (constant("$c::$constant") == "abstract") { throw new Exception("Undefined $constant in " . (string) $c); } } } } 

К сожалению, нет … константа – это именно то, что она говорит о жесте, постоянное. После определения он не может быть переопределен, поэтому таким образом невозможно определить его определение через абстрактное наследование или интерфейсы PHP.

Однако … вы можете проверить, определена ли константа в конструкторе родительского класса. Если это не так, бросьте исключение.

 abstract class A { public function __construct() { if (!defined('static::BLAH')) { throw new Exception('Constant BLAH is not defined on subclass ' . get_class($this)); } } } class B extends A { const BLAH = 'here'; } $b = new B(); 

Это лучший способ, я могу думать об этом из вашего первоначального описания.

Это может быть немного «взломан», но делает работу с очень небольшим усилием, но просто с другим сообщением об ошибке, если константа не объявлена ​​в дочернем классе.

Объявление самореферентной константы синтаксически корректно и анализирует без проблем, только бросая ошибку, если это объявление действительно выполняется во время выполнения, поэтому самореферентное объявление в абстрактном классе должно быть переопределено в дочернем классе иначе произойдет фатальная ошибка : Cannot declare self-referencing constant .

В этом примере абстрактный родительский класс Foo заставляет всех своих детей объявлять переменную NAME . Этот код работает отлично, выводя Donald . Однако, если дочерний класс Fooling не объявил переменную, будет вызвана фатальная ошибка.

 <?php abstract class Foo { // Self-referential 'abstract' declaration const NAME = self::NAME; } class Fooling extends Foo { // Overrides definition from parent class // Without this declaration, an error will be triggered const NAME = 'Donald'; } $fooling = new Fooling(); echo $fooling::NAME; 

Нет, но вы можете попробовать другие способы, такие как абстрактные методы:

 abstract class Fruit { abstract function getName(); abstract function getColor(); public function printInfo() { echo "The {$this->getName()} is {$this->getColor()}"; } } class Apple extends Fruit { function getName() { return 'apple'; } function getColor() { return 'red'; } //other apple methods } class Banana extends Fruit { function getName() { return 'banana'; } function getColor() { return 'yellow'; } //other banana methods } 

или статические элементы:

 abstract class Fruit { protected static $name; protected static $color; public function printInfo() { echo "The {static::$name} is {static::$color}"; } } class Apple extends Fruit { protected static $name = 'apple'; protected static $color = 'red'; //other apple methods } class Banana extends Fruit { protected static $name = 'banana'; protected static $color = 'yellow'; //other banana methods } 

Источник