15

为什么我不能使用这样的代码?

<?php

class NoConstructor {
}

class ChildWithConstructor extends NoConstructor {
    public function __construct() {
        parent::__construct();
        // do something
    }
}

$foo = new ChildWithConstructor();
// **Fatal error: Cannot call constructor in file.php on line 8**

例如。Java 类有默认的,没有 args 构造函数。即使没有明确定义,也可以调用它。

当我们从父类中删除没有 args 构造函数时,PHP 行为可能会导致麻烦,例如。当我们认为不再需要它时。

有谁知道为什么 PHP 创建者会这样做?

4

4 回答 4

24

Java 类有默认的,没有 args 构造函数。

有谁知道为什么 PHP 创建者会这样做?

Java 是一种有计划的语言。它从一开始就经过严格考虑和正式指定。为了向后和向前兼容性,为了简化开发人员和实施人员,它旨在尽可能长时间地使用最少的更改。绝对没有达到他们希望的程度,但是您仍然可以获取 Java 1.0 代码,编译它并在现代 VM 上运行它。

PHP 的设计者从未将这种语言设计得如此极端。他们一边走一边弥补。无论好坏,他们都愿意将语言分开并在下一个版本中重建它。自 PHP 1 和 2 以来,它发生了无法辨认的变化。甚至在最近,在 PHP 5 中,对象的按值语义到按引用语义发生了巨大变化。error_reporting(-1);正是这种出色的方法为我们带来了魔术引号、缺乏 Unicode、名称不一致(并且经常重命名)的函数,以及一个甚至没有任何错误提示(即使09使用0.

当我们从父类中删除没有 args 构造函数时,PHP 行为可能会导致麻烦,例如。当我们认为不再需要它时。

您可以在 bugs.php.net 上请求更改此内容,但他们可能会忽略它,或者用“对不起,但您的问题并不意味着 PHP 本身存在问题......”来欺骗您。

于 2011-10-26T21:50:43.807 回答
4

正如我们在5.3.7 灾难中看到的那样,PHP 开发可能需要更多的稳定性。除此之外,PHP 在很多方面都不同。

  • 企业备份不在同一个联盟中(没有 Oracle、没有 IBM 等)
  • PHP 很旧,有时不一致
  • PHP 的解释器(Zend 引擎)必须能够通过支持如此多的遗留结构和编程范式来做很多事情。
  • PHP 的起源是一种简单的脚本语言,供爱好者使用。

我真的很喜欢 PHP 并且每天都在使用它,但有时它只是一个小怪癖。另一方面,如果您删除 __construct() ,您应该考虑两件事。

  1. 永远不要这样做,只是清空构造函数
  2. 如果您正在构建一个框架,请将 init 函数作为核心概念,因为这些甚至是很好的实践。

我的意思是:

class BaseClass {
  public function __construct() {
      if(method_exists($this, 'init') {
          $this->init();
      }
  }
}
于 2011-10-26T21:40:21.597 回答
1

在 PHP 5 之前,构造函数与类同名,例如 JAVA。在 PHP 5 中,一个类可以有一个与类同名(如果不在命名空间中)或命名为 __construct 的构造方法。也许与此有关。

于 2011-10-26T21:38:32.930 回答
1

线

parent::__construct();

是对父类的构造函数的显式调用。“PHP”给你一个错误,因为它不存在。

你真的可以在 Java 中显式调用父级不存在的构造函数并且不会出错吗?

请记住,扩展父类的类的构造函数将在构造扩展类时覆盖父类的构造函数。调用父构造函数意味着您期望它做某事。如果构造函数不存在,那么无论解释器是否给您错误,您对它的调用都不属于代码。

于 2011-10-26T22:08:24.530 回答