PHP接口实现拒绝参数的子类

fab*_*bio 5 php interface subclass type-hinting interface-implementation

考虑一下:

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){}
}
Run Code Online (Sandbox Code Playgroud)

在我的构思中,上述应该有效,但它并不像php那样拒绝那种要求第一个参数与接口(I)中定义的完全相同的类型(A)的实现.既然B是A的子类,我看不出问题是什么.我在这里错过了什么吗?

Aiv*_*var 7

class C implements I意味着C和之间必须存在子类型关系I.这意味着类型C的对象应该可以在I需要类型的对象的任何地方使用.

在你的情况下,C它的限制性要大于I因为它对其doSomething参数有更精确的要求- I.doSomething对任何一个都很好AC.doSomething需要一个特定的子类型A

请注意,如果您更改C.doSomething为接受any,A则不会阻止您将类型的对象传递给它B.你只是不能要求B,因为那样你就会破坏子类型合同.

从理论上讲,子类型可以对其函数参数更加自由,更具体地说它们的返回类型(但反之亦然,就像在你的情况下一样).实际上,编程语言可能要求重写方法中的参数类型必须在任何地方都相同.