consider this:
class A{}
class B extends A{}
interface I{
// expects object instanceof A
function doSomething(A $a);
}
class C implements I
{
// fails ????
function doSomething(B $b){}
}
In my conception the above should work but it doesn't as php rejects that implementation requiring the first parameter to be exactly the same type (A) as defined in the interface (I). Since B is a subclass of A, I don't see whats the problem. Am I missing something here?
class C implements I
means that there must be subtype relation between C
and I
. It means object of type C
should be usable wherever an object of type I
is required.
In your case C
is more restrictive than I
because it has more precise requirements on its doSomething
argument -- I.doSomething
is fine with any A
but C.doSomething
requires a specific subtype of A
Note that if you change C.doSomething
to accept any A
then nothing prevents you to pass it an object of type B
. You just can't require only B
, because then you would break subtyping contract.
In theory, subtypes can be more liberal about their function arguments and more specific about their return types (but never vice versa, as it was in your case). In practice, a programming language may require that argument types in overridden methods must be same everywhere.
In theory, subtypes can be more liberal about their function arguments and more specific about their return types (but never vice versa, as it was in your case). In practice, a programming language may require that argument types in overridden methods must be same everywhere.
little work around- instanceof
to solve that problem:
class A{}
class B extends A{}
interface I{
// expects object instanceof A
function doSomething(A $a);
}
class C implements I
{
function doSomething(A $b){
if($b is instance of B){
//do something
}else{throw new InvalidArgumentException("arg must be instance of B") };
}
}
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