【发布时间】:2020-07-16 08:10:10
【问题描述】:
假设我有三个这样的课程。
abstract class A {
abstract protected function doSomething($object): array;
}
class B extends A {
protected function doSomething(SomeObject $object): array
{
// something
}
}
class C extends A {
protected function doSomething(OtherObject $object): array
{
// something
}
}
根据 PHP 的继承原则,上述结构不是合法的 PHP 代码,因为方法定义与基类不兼容。当然,我可以做类似的事情
class B extends A {
protected function doSomething($object): array
{
if (!is_a($object, 'SomeObject')) {
throw new Exception('Object passed to method is not of the correct class for this method.');
}
// something
}
}
但我想知道是否有另一种解决方案来实现抽象类中的方法,该方法可以重新定义为只接受其中特定类型的对象。
【问题讨论】:
-
您的对象可以实现相同的接口,然后您可以将该接口作为参数类型传递
-
使子类的参数比基类参数更窄/更具体是违反 Liskov 替换原则,即如果超类 A 中的方法接受 B 类的参数并返回类 C 的对象,那么重新实现该方法的 A 的子类只能修改使得参数可以是 B 类的超类(逆变),返回类型可以是 C 类的子类(协方差)
标签: php oop solid-principles liskov-substitution-principle