Why are method declarations incompatible?

Why am I getting this error:

Fatal error: Declaration of ConcreteFooMapper::load() must be compatible with that of AbstractFooMapper::load() on line 18 

from this code:

 <?php interface Foo { public function foo(); } class ConcreteFoo implements Foo { public function foo() { } } abstract class AbstractFooMapper { abstract public function load(Foo $entity, array $data); } class ConcreteFooMapper extends AbstractFooMapper { public function load(ConcreteFoo $entity, array $data) { } } ?> 

My initial thought is that this is a mistake; PHP does not detect that ConcreteFoo implements Foo when it evaluates the declaration of the it method. I think this is because when you run this code:

 <?php interface Foo { public function foo(); } class ConcreteFoo implements Foo { public function foo() { } } $foo = new ConcreteFoo(); if ($foo instanceof Foo) { print 'w00t!'; } else { print 'FAIL!'; } ?> 

he prints w00t! indicating ConcreteFoo is an instance of Foo .

Any understanding of whether this behavior is correct or not?

+4
source share
2 answers

A class that implements the interface must use the same method signatures that are defined in the interface. This will not result in a fatal error. And the same rules for classes that extend abstract classes.

For more details see here . See here

And this is the correct behavior \ logic.

check here Abstract types are useful in that they can be used to define and enforce the protocol; A set of operations that all objects implementing the protocol must support.

if we assume that your code will work without exception, then we have the following problem: ConcreteFooMapper cannot use instances of some class ConcreteFoo2 implements Foo parameter class ConcreteFoo2 implements Foo as a parameter for the load method, but should (by the definition of an abstract class)

In addition, if you use the same signature, this is not a problem, because all information about the class \ type is available. Please check the following code

 <?php interface Foo { public function foo(); } class ConcreteFoo implements Foo { public function foo() { } } abstract class AbstractFooMapper { abstract public function load(Foo $entity, array $data); } class ConcreteFooMapper extends AbstractFooMapper { public function load(Foo $entity, array $data) { var_dump($entity instanceof Foo); var_dump($entity instanceof ConcreteFoo); } } $someConcreteFoo = new ConcreteFoo(); $someFooMapper = new ConcreteFooMapper(); $someFooMapper->load($someConcreteFoo, array('somekey' => 'somevalue')); // output // bool(true) bool(true) ?> 
+2
source

According to the docs , type hints must match exactly.

+3
source

All Articles