php - 在接口(interface)实现中覆盖参数类型

标签 php oop

假设我有一个模型接口(interface):

interface Model
{
}

接口(interface)中的一个函数接收该模型作为参数:

interface Service
{
    public function add(Model $model);
}

为什么,当我使用另一个实现上述服务的模型来实现该服务时:

class AnotherModel implements Model
{
}

class AnotherService implements Service
{
    public function add(AnotherModel $model);
}

我收到这个错误:

Fatal error: Declaration of AnotherService::add() must be compatible with Service::add(Model $model)

最佳答案

当您扩展一个类或实现一个接口(interface)时,您不允许对继承方法的任何类型或可见性约束进行比父类更严格的约束。这意味着如果您在父级中有一个公共(public)方法,则不允许将其设置为 protected /私有(private)。如果父方法接受某种特定类型的参数(在本例中为 Model),则不允许将它接受的参数限制为某种更特定的类型。

这就是您在这里所做的 - 您的 Service::add() 接受类型为 Model 的元素,但是 AnotherService 中的实现接受只有 个类型为AnotherModel 的对象。这意味着即使您有另一个实现 Model 的类,例如“class YetAnotherModel implements Model”,AnotherService::add() 不会接受它,因为 YetAnotherModel 不是 AnotherModel 的实例,即使它们实现了相同的接口(interface)。 所以 AnotherService::add() 不会接受 YetAnotherModel 类的对象,即使你实现了 Service 接口(interface)说“我接受我的 add() 方法”。

请参阅https://en.wikipedia.org/wiki/Liskov_substitution_principle了解更多详情。

关于php - 在接口(interface)实现中覆盖参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31517503/

相关文章:

javascript - 在页面滚动上加载更多内容的 Keyup/KeyDown 的结果

javascript - 无法通过 AJAX 发送数组

php - MySQLi 的编码问题

php - 如何将数组中的 php 变量传递给 javascript?

delphi - 如何声明数组属性?

c# - C#是否可以将基类的实例用于子类的不同实例?

Java获取父类(super class)方法在子类调用时使用子类实例方法

php - 可捕获的 fatal error :传递给 Foo::bar() 的参数 1 必须实现接口(interface) BazInterface,给定为空

php - 如何使用下面的代码切换类?

c++ - 使用 boost 指针会改变您的 OO 设计方法吗?