Есть ли способ определить свойства абстрактного класса в PHP?
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
php
oop
abstract-class
Тамаш Пап
источник
источник
Нет, нет способа принудительно применить это с помощью компилятора, вам придется использовать проверки времени выполнения (скажем, в конструкторе) для
$tablename
переменной, например:Чтобы обеспечить это для всех производных классов Foo_Abstract, вам нужно будет создать конструктор Foo_Abstract
final
, предотвращающий переопределение.Вместо этого вы можете объявить абстрактный получатель:
источник
В зависимости от контекста свойства, если я хочу принудительно объявить свойство абстрактного объекта в дочернем объекте, мне нравится использовать константу с
static
ключевым словом для свойства в конструкторе абстрактного объекта или методах установки / получения. При желании вы можете использоватьfinal
для предотвращения переопределения метода в расширенных классах.В остальном дочерний объект переопределяет свойство и методы родительского объекта, если они были переопределены. Например, если свойство объявлено как
protected
в родительском и переопределено какpublic
в дочернем, результирующее свойство будет общедоступным. Однако, если свойство объявленоprivate
в родительском элементе, оно останетсяprivate
недоступным для дочернего элемента.http://www.php.net//manual/en/language.oop5.static.php
источник
Как было сказано выше, такого точного определения не существует. Однако я использую этот простой обходной путь, чтобы заставить дочерний класс определять «абстрактное» свойство:
источник
static
недвижимостью.the only "safe" methods to have in a constructor are private and/or final ones
, разве мой обходной путь не такой?$name
. Вы можете реализовать этуsetName()
функцию без ее фактической настройки$name
.getName
вместо$name
работает лучше.abstract class Father { abstract protected function getName(); public function foo(){ echo $this->getName();} }
Я задал себе тот же вопрос сегодня и хочу добавить свои два цента.
Причина, по которой нам нужны
abstract
свойства, состоит в том, чтобы убедиться, что подклассы определяют их и генерируют исключения, когда они этого не делают. В моем конкретном случае мне нужно было что-то, что могло бы работать сstatic
союзником.В идеале хотелось бы примерно такого:
Я закончил с этой реализацией
Как видите, в
A
я не определяю$prop
, но использую вstatic
геттере. Следовательно, следующий код работаетВ
C
, с другой стороны, я не определяю$prop
, поэтому получаю исключения:Я должен вызвать
getProp()
метод, чтобы получить исключение, и я не могу получить его при загрузке класса, но это довольно близко к желаемому поведению, по крайней мере, в моем случае.Я определяю ,
getProp()
как ,final
чтобы избежать , что некоторые умный парень (он же сам в течение 6 месяцев) искушается сделатьисточник
Как вы могли понять, просто протестировав свой код:
Нет, нет. Свойства не могут быть объявлены абстрактными в PHP.
Однако вы можете реализовать абстрактную функцию получения / установки, это может быть то, что вы ищете.
Свойства не реализованы (особенно общедоступные), они просто существуют (или нет):
источник
Потребность в абстрактных свойствах может указывать на проблемы дизайна. Хотя многие ответы реализуют своего рода шаблон метода шаблона, и он работает, это всегда выглядит странно.
Давайте посмотрим на исходный пример:
Отметить что-либо
abstract
- значит указать, что это обязательная вещь. Ну, обязательное значение (в данном случае) является обязательной зависимостью, поэтому оно должно быть передано конструктору во время создания экземпляра :Затем, если вам действительно нужен более конкретный именованный класс, вы можете наследовать так:
Это может быть полезно, если вы используете контейнер DI и вам нужно передавать разные таблицы для разных объектов.
источник
PHP 7 значительно упрощает создание абстрактных «свойств». Как и выше, вы будете создавать их, создавая абстрактные функции, но в PHP 7 вы можете определить тип возвращаемого значения для этой функции, что значительно упрощает работу при создании базового класса, который может расширять кто угодно.
источник
если значение tablename никогда не изменится в течение жизни объекта, ниже будет простая, но безопасная реализация.
Ключевым моментом здесь является то, что строковое значение «пользователи» указывается и возвращается непосредственно в getTablename () в реализации дочернего класса. Функция имитирует свойство «только для чтения».
Это довольно похоже на решение, опубликованное ранее, в котором используется дополнительная переменная. Мне также нравится решение Марко, хотя оно может быть немного сложнее.
источник