这不好吗?或者这在PHP框架中很常见?
例如,在父类中,有一个save()函数,它返回数据库中受影响的行数。然后在子类中,我重写此函数以进行一些预验证,并且还想简单地返回成功/失败的布尔值。
答案 0 :(得分:5)
我同意一致认为改变返回值的类型(甚至含义)是不好的。
以下是一个不好的例子:
假设您有一个接受字符串和'Writer'的函数:
function printThroughWriter(String $text, Writer $writer) {
$count = $writer->write($text);
print "Writer '".get_class($writer)."' printed $count characters.";
}
这是最初的'作家'课程:
class Writer {
public function write(String $text) {
print $text;
return strlen($text);
}
}
如果我们将'LazyWriter'传递给函数
,该怎么办?class LazyWriter extends Writer {
public function write(String $text) {
return true;
}
}
假设Writer::write()
的返回值是printThroughWriter
中的字符数已被破坏,从而导致不一致。
答案 1 :(得分:3)
是的,这很糟糕。该方法的客户很难知道要期待。除非,该方法旨在处理它(在这种情况下,它似乎不是)。
我会强烈反对。
答案 2 :(得分:3)
您应该覆盖基础代码,而不是合同。
所以,不,改变返回值(这是合同的一部分)并不好。
答案 3 :(得分:2)
虽然在PHP中没有强制执行返回类型,但最好与重写方法保持一致,因为否则意味着您将增加耦合并减少封装。
考虑公共方法及其在出口和设备方面的退货类型。任何设备都应该能够插入任何插座,并且每个插座应该向每个设备输出相同的能量,除非插座是专门为特定类型的设备设计的。如果有人认为绿色出口应输出一定量的能量,而另一个则输出红色能量,会发生什么。突然间,您必须始终关注设备正在处理的特定类型的插座。
设计公共方法和属性完全相同,重写的方法和属性应始终表现一致,无论访问它们的上下文如何。
答案 4 :(得分:2)
我同意,这通常是一个坏主意。
如果你迫切需要从函数中传递另一个值,除了它的返回值,你可以添加一个pass-by-reference参数。或者,如果出现错误消息,请使用例外。
答案 5 :(得分:2)
继承的想法是允许客户端交换使用类的子类型。如果要更改子类型的返回类型,那么您正在破坏继承的规范实用程序,并最终会造成混淆: “我在这里采用了一种类型的集合,但是myCollection.add()会给我一个布尔值或者添加的元素或其他东西吗?我不知道!我不能再用这种类型做任何事了!我我将不得不为每个子类型创建一个方法来处理这个问题!“
答案 6 :(得分:1)
您可以从重写方法返回更多指定类型,例如返回类型的后代实例,而不会违反合同。
如果重写的方法返回了一个布尔值,则重写方法可以返回一个数字,如果0
返回值对应于将导致重写方法返回FALSE
并且非零值对应的条件到TRUE
返回值。如果有人在返回值上使用相同的比较运算符(===
),这仍然可能会导致问题,但是通常只有在(例如)方法可能同时返回FALSE
和{{1}时才会看到此问题在不同的条件下。
在您的示例中,覆盖返回类型并不比重写的返回类型更具体,因此您不应该这样做。
答案 7 :(得分:0)
我最终在这里寻找正确的做事方式。 就我而言,我是在谈论测试课程:
这就是我解决的方法:
我真的很喜欢这个解决方案,因为通过CtrlStorm并单击phpStorm,可以找到原始方法。
在其他情况下,可能不会更改返回类型,正如其他人所解释的那样,但是see标记可以类似的方式使用。
希望有帮助!继续摇摆;)