I think it'll be much easier to see the problem in a code example than writing the question in the first place. Here is my php code:
<?php
interface AnInterface
{
public function method();
}
class AClass implements AnInterface
{
public function method()
{
echo __METHOD__;
}
}
abstract class AnAbstractClass
{
abstract public function method( AnInterface $Object );
}
class ConcreteClass extends AnAbstractClass
{
public function method( AClass $Object )
{
$Object->method();
}
}
$Object1 = new ConcreteClass();
$Object2 = new AClass();
$Object1->method( $Object2 );
The above code causes the following error:
Fatal error: Declaration of ConcreteClass::method() must be compatible with that of AnAbstractClass::method()
The problem is that php doesn't seem to be recognizing the signatures of AnAbstractClass::method and ConcreteClass::method as compatible. Am I doing something wrong? Thanks!
PHP has abstract classes and methods. Classes defined as abstract cannot be instantiated, and any class that contains at least one abstract method must also be abstract.
In simple word, type hinting means providing hints to function to only accept the given data type. In technical word we can say that Type Hinting is method by which we can force function to accept the desired data type. In PHP, we can use type hinting for Object, Array and callable data type.
Like C++ or Java abstract class in PHP can contain constructor also.
php doesn't seem to be recognizing the signatures of
AnAbstractClass::method
andConcreteClass::method
as compatible.
PHP is correct, they're not compatible. By allowing only instances of AClass
(or its children) to be passed to ConcreteClass::method
, you're breaking the contract that AnAbstractClass
provides: Any of its subclasses must accept AnInterface
as an argument to its method()
.
If your example worked, and I had another class BClass
implementing AnInterface
, we'd have a situation where according to AnAbstractClass
, method()
should accept instances of BClass
, while according to ConcreteClass
, it shouldn't.
Change your signature for ConcreteClass::method
to match that of AnAbstractClass::method
.
Here's an example that shows, why this is not allowed:
<?php
class BClass implements AnInterface { }
function moo(AnAbstractClass $abstract)
{
$b = new BClass();
$abstract->method($b);
}
This would be a valid code, but it would fail, if you pass a ConcreteClass
to moo, because its method ConcreteClass::method
does not allow BClass
.
It is complicated, but it is easier to understand, if you see an example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With