Этот код работает нормально.
ParentClass
это абстрактный класс. Я думаю, что могу проверить это
$class = new ReflectionClass('ParentClass');
$methods = $class->getMethods(ReflectionMethod::IS_ABSTRACT);
который показывает пару методов, один из которых назван methodA
,
Вот что действительно сбило меня с толку:
Eсть ChildClass
и это конкретный класс и реализует один из абстрактного метода methodA
, С помощью
$method = new ReflectionMethod('ChildClass', 'methodA');
var_dump($method->getParameters());
Я могу проверить, что есть 3 параметра. Поскольку я знаю, что код работает хорошо. Я использовал тот же ReflectionMethod, чтобы проверить ParentClass
$method = new ReflectionMethod('ParentClass', 'methodA');
var_dump($method->getParameters());
Это выводит пустой массив, который не указывает ни одного параметра, я полагаю.
Зачем? К сожалению, я не могу посмотреть на исходный код этих классов, но я пытался понять это без особого прогресса:
Пока что я могу делать только такие вещи. Код в PHP5.4. Я действительно не могу понять, как сделать абстрактный метод _myFunction
без аргументов, но конкретный метод дочернего класса с 3 аргументами. PHP использует __call
перегружать, но это больше extending
проблема, я полагаю.
class A {}
abstract class MyAbstractClass
{
//abstract public function _myFunction();// ERROR
abstract public function _myFunction(A $a, A $b, A $c);
}
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a, A $b, A $c = null)
{
echo "abc";
}
}
$a = new Foobar();
$a->_myFunction(new A(), new A(), new A());
$a->_myFunction(new A(), new A());
//output: abcabc without error
Добавлено:
После того, как я записал вопрос, это помогает мне продолжить мой тест, я думаю, что теперь знаю почему. Дочерний метод дал всем 3 аргументам значение по умолчанию.
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a = null, A $b = null, A $c = null)
{
echo "abc";
}
}
Это будет работать.
Согласно Руководство по PHP:
При наследовании от абстрактного класса все методы, помеченные как абстрактные в объявлении класса родителя, должны быть определены дочерним объектом; Кроме того, эти методы должны быть определены с одинаковой (или менее ограниченной) видимостью.
Кроме того, сигнатуры методов должны совпадать, то есть подсказки типа и количество обязательных аргументов должны быть одинаковыми.
Итак, родительский класс имеет 0 аргументов, дочерний — 2 требуется из них. Это проблема. Но так как вы изменили свой код, как вы говорите:
Дочерний метод дал всем 3 аргументам значение по умолчанию.
Вы сократили количество обязательных аргументов в дочернем классе до 0. Так что теперь это работает.
Перепросматривать. Это не верно:
abstract class MyAbstractClass
{
abstract public function _myFunction(); // No parameters required
}
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a, A $b, A $c = null) // Two parameters required
{
echo "abc";
}
}
Это также было бы неправильно:
abstract class MyAbstractClass
{
abstract public function _myFunction(A $a, A $b, A $c); // Three parameters required
}
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a, A $b) // Two parameters required
{
echo "abc";
}
}
Это нормально:
abstract class MyAbstractClass
{
abstract public function _myFunction(); // No parameters required
}
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a = null, A $b = null, A $c = null) // No parameters required
{
echo "abc";
}
}
И это тоже нормально
abstract class MyAbstractClass
{
abstract public function _myFunction(A $a, A $b, A $c);
}
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a, A $b, A $c = null)
{
echo "abc";
}
}
Других решений пока нет …