Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中重写子类中的函数时更改返回类型?_Php_Function_Overriding_Return Type - Fatal编程技术网

在PHP中重写子类中的函数时更改返回类型?

在PHP中重写子类中的函数时更改返回类型?,php,function,overriding,return-type,Php,Function,Overriding,Return Type,这不好吗?或者这在PHP框架中非常常见? 例如,在父类中,有一个save()函数,它返回数据库中受影响的行数。然后在子类中,我重写此函数以进行一些预验证,并且只想返回一个成功/失败的布尔值。是,这是错误的。这种方法的客户将很难知道这一点。除非该方法是为处理它而设计的(在本例中,似乎不是这样) 我强烈建议您不要这样做。您应该覆盖底层代码,而不是合同 因此,不,更改返回值(这是合同的一部分)是不好的。虽然在PHP中没有强制执行返回类型,但最好与重写的方法保持一致,否则会增加耦合并减少封装 考虑一下公

这不好吗?或者这在PHP框架中非常常见?


例如,在父类中,有一个save()函数,它返回数据库中受影响的行数。然后在子类中,我重写此函数以进行一些预验证,并且只想返回一个成功/失败的布尔值。

是,这是错误的。这种方法的客户将很难知道这一点。除非该方法是为处理它而设计的(在本例中,似乎不是这样)


我强烈建议您不要这样做。

您应该覆盖底层代码,而不是合同


因此,不,更改返回值(这是合同的一部分)是不好的。

虽然在PHP中没有强制执行返回类型,但最好与重写的方法保持一致,否则会增加耦合并减少封装

考虑一下公共方法及其在门店和电器方面的回报类型。任何设备都应该能够插入任何插座,并且每个插座都应该向每个设备输出相同的能量,当然,除非插座是专门为特定类型的设备设计的。如果有人决定绿色插座输出一种能量,红色插座输出另一种能量,会发生什么。突然之间,你必须始终关注你的设备正在处理的特定类型的插座


设计公共方法和属性是完全相同的,被重写的方法和属性应该始终保持一致的行为,而不管它们在什么上下文中被访问。

我同意这样的共识,即更改返回值的类型(甚至含义)是不好的

下面是一个例子,说明它将如何变得糟糕:

假设您有一个接受字符串和“Writer”的函数:

function printThroughWriter(String $text, Writer $writer) {
    $count = $writer->write($text);
    print "Writer '".get_class($writer)."' printed $count characters.";
}
这是最初的“Writer”课程:

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
中的字符数,这一假设已被打破,从而导致了不一致性。

我同意,这通常是一个坏主意


如果您迫切需要从函数中传递另一个值,而不是它的返回值,则可以添加“按引用传递”参数。或者,在出现错误消息的情况下,使用异常。

继承的思想是允许客户机互换地使用类的子类型。如果您正在更改子类型的返回类型,那么您将破坏继承的规范性实用程序,并最终导致混淆:
“这里我使用一种类型的集合,但是myCollection.add()是否会返回一个布尔值或添加的元素或其他东西?我不知道!我不能再使用这种类型了!我必须为每个子类型创建一个方法才能处理此问题!”

您可以返回更指定的类型,例如,在不破坏约定的情况下,来自重写方法的返回类型的子体的实例

如果重写方法返回布尔值,则如果
0
返回值与导致重写方法返回
FALSE
的条件相对应,且非零值与
TRUE
返回值相对应,则重写方法可以返回数字。如果有人对返回值使用相同的比较运算符(
==
),这仍然可能会导致问题,但通常只有在(例如)方法可能在不同条件下同时返回
FALSE
0
时才会看到这一点


在您的示例中,重写的返回类型并不比重写的返回类型更具体,因此您不应该这样做。

我在这里寻找正确的方法。 在我的例子中,我说的是一个测试类:

  • 原始方法返回一个bool:success | failure
  • 测试方法返回了一个数组,而不是,以返回一些调试信息
我就是这样解决的:

  • 在方法名称前增加“test”前缀
  • 在php文档注释中,我添加了一个@see标记,后跟原始方法名
我真的很喜欢这个解决方案,因为通过用phpStorm按Ctrl键,我可以找到原来的方法

在其他情况下,正如其他人所解释的,我可能不会更改返回类型,但是see标记可以以类似的方式使用

希望有帮助!继续摇摆;)