Подтвердить что ты не робот

Почему PHP 5.2+ запрещает использование абстрактных методов статического класса?

После включения строгих предупреждений в PHP 5.2 я увидел загрузку строгих предупреждений о стандартах из проекта, который был изначально написан без строгих предупреждений:

Строгие стандарты: Статическая функция Программа:: getSelectSQL() не должна быть абстрактной в Program.class.inc

Эта функция относится к абстрактной родительской программе классов и объявляется абстрактной статикой, потому что она должна быть реализована в своих дочерних классах, таких как TVProgram.

Я нашел ссылки на это изменение здесь:

Выброшены абстрактные статические функции класса. Из-за недосмотра PHP 5.0.x и 5.1.x допускали абстрактные статические функции в классах. Начиная с PHP 5.2.x, только интерфейсы могут иметь их.

Мой вопрос: может ли кто-нибудь объяснить в ясной форме, почему в PHP не должно быть абстрактной статической функции?

4b9b3361

Ответ 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 для создания класса с аналогичной функциональностью.