Могу ли я указать нестрогие требования к методам для дочерних классов?

У меня есть базовый класс, в котором я хочу указать методы, которые должен иметь дочерний класс, но не реализовать их сам. Однако методы в дочернем классе могут иметь другое количество параметров, чем определение в базовом классе.

Попробовав это абстрактным методом, php этого не позволяет. Является ли это возможным?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
1 129
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

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

Обратной стороной является использование только одного аргумента и требование передачи всех аргументов через массивы.

Sean McSomething 12.12.2008 07:45

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

Действительно, можно сделать то, о чем вы говорите, как своего рода взлом, обоими способами, упомянутыми выше, с помощью:

func_get_args()

или просто (как упомянул комментатор) передать массив аргументов. В качестве альтернативы вы можете передать объект, у которого есть ваши аргументы как члены данных. Затем вы можете расширить объект параметра / аргумента для своего дочернего метода.

Дело в том, что PHP - это язык, который процветает на вседозволенности, а не на ограничениях. Абстрактные классы имеют очень простую реализацию в PHP. Если вам нужно много подобной структуры, то PHP действительно может быть не лучшим выбором языка.

Я не думаю, что это ответ, который вы захотите использовать в продакшене, поскольку он будет довольно медленным, но просто ради этого я попытался написать что-то с использованием Reflection, которое, похоже, работает. Вы все равно получите E_STRICT, потому что объявления методов в подклассах, по-видимому, должны совпадать.

class a {
    protected $requiredMethodsInSubclass = array( 'method1', 'method2', 'method3' );

    public function __construct() {
        $reflObject = new ReflectionObject($this);

        $className = $reflObject->getName();

        if ($className == __CLASS__) {
            //this class is being instanciated directly , so don't worry about any subclasses
            return;
        }

        foreach ($this->requiredMethodsInSubclass as $methodName) {
            try {
                $reflMethod = $reflObject->getMethod($methodName);
            } catch (ReflectionException $e) { //method not anywhere
                trigger_error("Method $methodName is not declared in class " . __CLASS__ . " or subclass $className", E_USER_ERROR);
                continue;
            }

            $declaringClass =  $reflMethod->getDeclaringClass();

            if ($declaringClass->getName() == __CLASS__) {
                //method is declared in this class, not subclass
               trigger_error("Method $methodName is not declared in subclass $className", E_USER_ERROR);
            }
        }
    }

    public function method1() {

    }

    public function method2($a) {

    }
 }



class b extends a {
    public function __construct() {
        parent::__construct();

        //some stuff
    }


    public function method2($a, $b, $c) {

    }

}



$b = new b();

Функция дочернего класса может добавлять дополнительные необязательные аргументы к подписи, не вызывая ошибок:

abstract class Foo {
  abstract function bar($a);
}

class NewFoo extends Foo {

  function bar($a, $b = null) {
    //do something
  }
}

Другие вопросы по теме