【问题标题】:Why doesn't PHP Strict Standards complain about difference in constructor arguments?为什么 PHP 严格标准不抱怨构造函数参数的差异?
【发布时间】:2014-12-10 22:20:57
【问题描述】:

通常,当子类具有与其父类不同的函数参数时,PHP 严格标准会让您知道:

严格标准:Boele::bla() 的声明应与 foo.php 中的 Oele::bla($one, Exception $two) 兼容

它不会破坏任何东西,但它会让你知道它并不酷。我同意。

然而,构造函数似乎得到了特殊待遇:

class Oele {
  function __construct($one, Exception $two) {}

  function bla($one, Exception $two) {}
}

class Boele extends Oele {
  function __construct(Exception $two) {}

  function bla(Exception $two) {}
}

__construct()bla() 方法在 parent 和 child 中都是不同的,但是 PHP 只通知 bla(),而不是 __construct()

Proof on 3v4l

为什么?? 对构造函数这样做不是同样“糟糕”吗?

(我在这里运行的是 PHP 5.5.17,但正如您在 3v4l 上看到的,它对所有 PHP 5 都一样。)

【问题讨论】:

    标签: php constructor strict


    【解决方案1】:

    我无法解释原因,但 PHP 文档中有关于此的信息:

    与其他方法不同,当 __construct() 使用与父 __construct() 方法不同的参数覆盖时,PHP 不会生成 E_STRICT 级别的错误消息。

    来源:http://php.net/manual/en/language.oop5.decon.php

    【讨论】:

    • 哦,哇,我怎么没看到!?至少我知道这是故意的。谢谢。
    【解决方案2】:

    一个主要原因是当你实例化一个类时,它只调用子构造函数。如果您还希望调用父构造函数,则必须使用parent::__construct() 显式调用它。假设子类将构建自己的构造函数并按照他们认为合适的方式实现父类。

    相比之下,如果(使用您的示例)我想调用Boele->bla(),则将两个函数命名为相同但参数不同可能会造成混淆。更糟糕的是,使用孩子呼叫Oele->bla() 并不容易。因此,用不兼容的函数覆盖父函数不是最佳做法。

    还要考虑 PHP 有多少种方法来约束实现类(抽象和接口)。在这些情况下,您必须使用相同的参数来实现它们,否则会出错。

    【讨论】:

    • 有道理,有点...我猜我也可以使用接口强制构造函数签名?不仅仅是方法?
    • 我不知道有什么方法可以强制孩子加载父构造函数
    • 我不是这个意思。如果我使用构造函数创建接口,则所有实现者都必须使用该函数签名,所以无论如何你都可以强制它:3v4l.org/qWTDI
    • 啊,是的,你可以用接口定义构造函数的样子
    猜你喜欢
    • 2016-04-17
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2019-09-14
    • 2017-05-28
    • 2012-12-29
    • 1970-01-01
    相关资源
    最近更新 更多