2016-02-28 5 views
2

Этот код работает нормально.Должно ли объявление метода дочернего класса быть совместимым с методом родительского класса в PHP?

ParentClass является абстрактным классом. Я думаю, что я могу проверить, что

$class = new ReflectionClass('ParentClass'); 
$methods = $class->getMethods(ReflectionMethod::IS_ABSTRACT); 

, который показывает несколько методов, один из которых назван methodA.

вот что действительно озадачило меня:

Там есть ChildClass и это конкретный класс и реализует один из абстрактного метода methodA. Использование

$method = new ReflectionMethod('ChildClass', 'methodA'); 
var_dump($method->getParameters()); 

Я могу проверить, что существует 3 параметра. Поскольку я знаю, что код работает хорошо. Я использовал тот же ReflectionMethod проверить ParentClass

$method = new ReflectionMethod('ParentClass', 'methodA'); 
var_dump($method->getParameters()); 

Этот вывод пустой массив, который указывает параметры NONE, я полагаю.

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

До сих пор я могу делать только такие вещи. Код находится в 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"; 
    } 
} 

Это будет работать.

ответ

1

По PHP manual:

При наследовании от абстрактного класса, все методы отмечены абстрактные в объявлении класса родителя должны быть определены ребенком; кроме того, эти методы должны быть определены с той же (или менее ограниченной) видимостью.

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

Таким образом, родительский класс имеет 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"; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^