【问题标题】:Class implementing an interface must be declared before a children class?实现接口的类必须在子类之前声明?
【发布时间】:2012-01-23 17:45:21
【问题描述】:

我今天偶然发现了一个有趣的问题。在单个文件的多个声明的上下文中,如果类B 实现了接口A,并且类C 扩展了类A,则必须在类@ 之前声明类B之前 987654326@.

以下代码不起作用:

interface A {}
class C extends B {} // Class 'B' not found
class B implements A {}

这解决了它:

interface A {}
class B implements A {}
class C extends B {} // Class 'B' is found

但这很好用:

class A {}
class C extends B {} // Class 'B' is found
class B extends A {}

这些是我在 PHP 5.3.8 (Win32) 和 PHP 5.3.3-1ubuntu9.6 w/suhosin 上的结果。

所以问题是,这是记录在案的行为吗?为什么它适用于类而不适用于接口?还是应该将其视为错误?

在我深入研究 PHP 的源代码和/或打开 PHP 错误票之前,请告诉我您的经验。 :)

谢谢!

注意:我知道这只是类声明顺序的问题,但这让我感到困惑......如果不合适,请不要犹豫关闭。

【问题讨论】:

  • 您在 Windows 下显然适用于您的第三个代码示例在 Debian、PHP 5.3.8-1~dotdeb.2 下不适用于我。我收到了致命错误。
  • @NB:有趣。在 Ubuntu 上的 5.3.3 中也适用于我。这里有些不一致,无论是行为还是文档。
  • 我直接从 shell 测试了代码(使用php -a)。没有偶然包含的框架或自动加载器。
  • 第三个示例也适用于我在使用 mamp pro 的 Mac 上。在 PHP 版本 5.2.17 和 5.3.5 上运行良好

标签: php inheritance interface


【解决方案1】:

是的,这是记录在案的行为:

Object Inheritance (Note):

除非使用自动加载,否则类必须在使用前定义。 如果一个类扩展另一个类,则必须在子类结构之前声明父类。此规则适用于继承其他类和接口的类。

 

PHP: extends - Manual (Note)

类必须在使用前定义!如果您希望 Named_Cart 类扩展 Cart 类,则必须首先定义 Cart 类。如果要基于 Named_Cart 类创建另一个名为 Yellow_named_cart 的类,则必须先定义 Named_Cart。简而言之:定义类的顺序很重要。


未定义的行为(带有讽刺意味)

尽管您的第三个示例可能会说话,但根据文档并没有说它可以工作(而且我找不到任何说明它是引入的功能的更改日志条目)。

遗憾的是,PHP 的文档不是 100%,但你只能相信你所知道的,关于这件事我能找到以上引用。

您可能称其为错误,但在 C++ 中我们会将其描述为undefined behavior 即。不应该依赖的东西。


如果“标准”(文档)未提及,则使用不安全。

如果“标准”(文档)没有提到它,它可能会使宇宙内爆——或者一只猛禽从你的窗户里跳出来。 不要做任何会杀死我们所有人的事情!

【讨论】:

  • 不一定是真的,我的第三个例子实际上挑战了这个说法。看看我用不同版本的 PHP 会得到什么...
  • +1 谢谢,这回答了我的问题,但这里肯定有问题。
  • @DmitriSnytkine:没有自动加载器。
  • @refp:我们与 C++ 中的 undefined behavior 相差甚远。就像您提到的那样,PHP 文档不是最新的已知问题,因为没有 ISO 标准来定义定义了什么行为,什么没有定义。文档(和语言)是由社区编写的,因此很容易不准确(过去经常看到)。我可以通过访问 C 中的未初始化变量来使宇宙内爆,但我认为 PHP 的功能不足以杀死我们所有人。 :)
  • @netcoder 我在字里行间充满了讽刺,但我肯定会引用你的话说,C 足够强大,足以让宇宙内爆,而 PHP 不是。我什至不喜欢 PHP,只是碰巧对它了解太多。我有更长的休息时间(我在办公室),我可能需要一些时间来挖掘 PHP 源代码,试图找出发生了什么。
猜你喜欢
  • 2013-10-08
  • 2011-08-06
  • 2012-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 2020-01-16
相关资源
最近更新 更多