gpt4 book ai didi

php - 代码是否符合 Liskov 替换原则?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:42:12 24 4
gpt4 key购买 nike

在升级之前,我正在 PHP5.4 上测试我现有的代码。我发现以下代码不再有效,因为 PHP 收紧了它的继承模型。由于收紧,我一直在阅读 SOLID ,特别是 Liskov's substitution principle (我是一个自学成才的程序员)这样我就可以改进我的代码并且不会遭受 future 的“紧缩”。

interface IComparable {
public function equals(self $other);
}

class A implements IComparable{
protected $var;

public function __construct($v){
$this->var=$v;
}

public function equals(self $other){
return ($this->var == $other->var) ? 'equal' : 'different';
}
}

$a1= new A(7);
$a2= new A(5);
$a3= new A(5);

echo $a1->equals($a2),"\n";
echo $a2->equals($a3),"\n";

php 5.3 结果:

  • 不同
  • 等于

php 5.4 结果:

PHP Fatal error: Declaration of A::equals() must be compatible with IComparable::equals(IComparable $other)

这样写代码可以避免php5.4的错误:

interface IComparable {
public function equals($other);
}

class A implements IComparable{
protected $var;

public function __construct($v){
$this->var=$v;
}

public function equals($other){
if(get_class($other) != get_class($this)) return false;
return ($this->var == $other->var) ? 'equal' : 'different';
}
}

但是修复是否符合 Liskov 的替换原则,因为该函数显然不会接受任何参数类型?如果没有,我如何编写一个可继承的函数来执行我需要的操作——比较相同类型的 2 个对象——并遵守良好的 OOD 原则?

最佳答案

首先:PHP 5.3 的行为是 bug , 所以你不能用它作为衡量任何其他方法的准绳。

展望 future ,您的 5.3 版本代码中已经违反了 LSP。考虑:

interface IComparable {
public function equals(self $other);
}

这表示“任何 IComparable 都可以将自己与任何其他 IComparable 进行比较”(比较的语义对于讨论并不重要). A 类 然后继续违反 LSP,因为它 支持与任何 IComparable 进行比较——只是与那些碰巧是 A 实例。

PHP 5.4 版本没有违反 LSP,因为新版本的 IComparable 说“我可以将自己与任何其他对象进行比较”,而这正是 class A 所做的

如果您的意图是保留 5.3 版本契约(Contract),则 IComparable 应为

interface IComparable {
public function equals(IComparable $other);
}

A类当然会使用相同的签名。这不会违反 LSP 并且它会在两个版本中正常工作。

如果您的意图是声明“IComparable 实例可以将自己与相同类型的实例进行比较,无论那是什么”,那么您就不走运了,因为无法使用方法签名来表达此约定并输入提示。

更新:原来你的意图是声明“这个类的实例可以比较它们自己”,而 IComparable 只是为了强制你不要忘记这样做。

在这种情况下,解决方案就是忘记 IComparable 并在 A::compare() 的签名中使用 self .你确实失去了编译器的强制你记住定义必要的方法,但恕我直言,这是一个小问题(特别是因为接口(interface)只声明了一个方法)。

关于php - 代码是否符合 Liskov 替换原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10516864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com