This code is running fine.
The ParentClass
is abstract class. I think I can verify that by
$class = new ReflectionClass('ParentClass');
$methods = $class->getMethods(ReflectionMethod::IS_ABSTRACT);
which shows a couple of methods, one of which is named methodA
.
Here comes what really baffled me:
There is a ChildClass
and it is a concrete class and implements one of the abstract method methodA
. Using
$method = new ReflectionMethod('ChildClass', 'methodA');
var_dump($method->getParameters());
I can verify that there are 3 parameters. Since I know the code is working good. I used the same ReflectionMethod to verify the ParentClass
$method = new ReflectionMethod('ParentClass', 'methodA');
var_dump($method->getParameters());
This output an empty array which indicates none parameters, I suppose.
Why? Sadly, I can't look at the source code of these classes but I have been trying to figure out this without much progress:
So far, I can only do things like this. The code is in PHP5.4. I really can't figure out how to make an abstract method _myFunction
without arguments but the concrete child class method with 3 arguments. PHP uses __call
to overload but this is more of a extending
issue, I suppose.
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
Added:
After writing down the question, it helps me to further my test, I think I know why now. The child method has given all 3 arguments a default value.
class Foobar extends MyAbstractClass
{
public function _myFunction(A $a = null, A $b = null, A $c = null)
{
echo "abc";
}
}
This would work.
As per PHP manual:
When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility.
Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same.
So, the parent class has 0 arguments, the child has 2 required ones. That is the problem. But since you changed your code, as you say:
The child method has given all 3 arguments a default value.
You reduced the number of required arguments in the child class to 0. So it works now.
To recapitate. This is wrong:
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";
}
}
This would also be wrong:
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";
}
}
This is okay:
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";
}
}
And this is also okay:
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";
}
}