Почему PHP 5.2+ запрещает использование абстрактных методов статического класса?
После включения строгих предупреждений в PHP 5.2 я увидел загрузку строгих предупреждений о стандартах из проекта, который был изначально написан без строгих предупреждений:
Строгие стандарты: Статическая функция Программа:: getSelectSQL() не должна быть абстрактной в Program.class.inc
Эта функция относится к абстрактной родительской программе классов и объявляется абстрактной статикой, потому что она должна быть реализована в своих дочерних классах, таких как TVProgram.
Я нашел ссылки на это изменение здесь:
Выброшены абстрактные статические функции класса. Из-за недосмотра PHP 5.0.x и 5.1.x допускали абстрактные статические функции в классах. Начиная с PHP 5.2.x, только интерфейсы могут иметь их.
Мой вопрос: может ли кто-нибудь объяснить в ясной форме, почему в PHP не должно быть абстрактной статической функции?
Ответы
Ответ 1
статические методы относятся к классу, который их объявил. При расширении класса вы можете создать статический метод с тем же именем, но на самом деле вы не реализуете статический абстрактный метод.
То же самое касается расширения любого класса статическими методами. Если вы расширяете этот класс и создаете статический метод одной и той же сигнатуры, вы фактически не переопределяете статический метод суперкласса
EDIT (16 сентября 2009 г.)
Обновите это. Запустив PHP 5.3, я вижу, что абстрактный статик вернулся, для хорошего или плохого. (см. http://php.net/lsb для получения дополнительной информации)
КОРРЕКЦИЯ (by philfreo)
abstract static
до сих пор не разрешен в PHP 5.3, LSB связан, но отличается.
Ответ 2
Для этой проблемы очень простая работа, которая на самом деле имеет смысл с точки зрения дизайна. Как писал Джонатан:
То же самое касается расширения любого класса статическими методами. Если вы расширяете этот класс и создаете статический метод одной и той же сигнатуры, вы фактически не переопределяете статический метод суперкласса
Итак, как работа вокруг, вы можете сделать это:
<?php
abstract class MyFoo implements iMyFoo {
public static final function factory($type, $someData) {
// don't forget checking and do whatever else you would
// like to do inside a factory method
$class = get_called_class()."_".$type;
$inst = $class::getInstance($someData);
return $inst;
}
}
interface iMyFoo {
static function factory($type, $someData);
static function getInstance();
function getSomeData();
}
?>
И теперь вы утверждаете, что любой класс подкласса MyFoo реализует статический метод getInstance и общедоступный метод getSomeData. И если вы не подклассы MyFoo, вы все равно можете реализовать iMyFoo для создания класса с аналогичной функциональностью.