【发布时间】:2019-10-29 18:29:26
【问题描述】:
以下代码是否直接违反了 Liskov 替换原则:
子类不应该破坏父类的类型定义。
class Baz {}
class Foo extends Baz {}
interface a
{
public function baz(Baz $baz);
}
class b implements a
{
public function baz(Foo $foo)
{
}
}
哪些结果:
致命错误:b::baz(Foo $foo) 的声明必须与 a::baz(Baz $baz) 兼容
【问题讨论】:
-
当您在界面中专门要求 Baz 时,您正在尝试输入子类型。尽管 Foo 是 Baz 的子类型,但它仍然不是请求的类。
-
@MHewison 这不是重点吗?这应该是可能的,问题是 PHP 不支持逆变和/或协变。
-
是的,你说得对,PHP 不支持它。由于 PHP 中的方法参数类型是不变的。必须至少遵守接口。在 PHP 中,您通常会创建一个适合您的实现的接口。所以我想,这通常不违反 LSP,但在 PHP 中不支持。
-
@MHewison 谢谢。那么看来我对LSP还不是很了解。对我来说,看起来 Foo 作为 Baz 的子类型应该可以替代 Baz。 子类型必须可以替代它们的基本类型 - Robert C. Martin
-
一个实现类似于
interface a { } class A implements a {} class B implements a {}然后class Bar { public function baz(a $implementation) {} }注意,接口代替父类型的位置。
标签: php oop covariance contravariance liskov-substitution-principle