覆盖接口实现中的参数类型

Jac*_*hen 4 php oop

我们假设我有一个模型接口:

interface Model
{
}
Run Code Online (Sandbox Code Playgroud)

以及接收该模型作为参数的接口中的函数:

interface Service
{
    public function add(Model $model);
}
Run Code Online (Sandbox Code Playgroud)

为什么,当我用另一个实现上述功能的Model实现该服务时,如下所示:

class AnotherModel implements Model
{
}

class AnotherService implements Service
{
    public function add(AnotherModel $model);
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

致命错误:AnotherService :: add()的声明必须与Service :: add(Model $ model)兼容

jed*_*ylo 7

扩展类或实现接口时,不允许对继承方法的任何类型或可见性约束比父类更严格.这意味着如果您在父级中有公共方法,则不允许将其设为受保护/私有.如果父方法接受某些特定类型的参数(在本例中为Model),则不允许将它接受的参数限制为某种更具体的类型.

这是你在做什么,在这里-你的服务:: Add()方法接受类型元素的模式,但在实施AnotherService接受ONLY类型的对象AnotherModel.这意味着即使你有另一个实现Model的类,例如" class YetAnotherModel实现Model ",AnotherService :: add()也不会接受它,因为YetAnotherModel不是AnotherModel的实例,即使它们实现了相同的接口.因此,即使您实现了"我接受我的add()方法中的所有模型"的Service接口,AnotherService :: add()也不会接受YetAnotherModel类的对象.

有关详细信息,请参阅https://en.wikipedia.org/wiki/Liskov_substitution_principle.