如果在PHP中不显式调用父类构造函数会发生什么?

9
我想知道为什么在PHP中我们必须显式调用父类构造函数?如果我们忘记在派生类中调用父类构造函数会发生什么?
我认为派生类将无法访问其父类的成员属性或方法,但在我试着不调用父类构造函数之后,似乎子类仍可以访问其父类的公共/受保护成员。
那么我们是否必须显式调用其父类构造函数?如果我们忘记这样做会有什么后果?
提前感谢您的帮助。任何形式的帮助都将不胜感激 :)

2
请查阅 PHP 官方手册,网址是 http://php.net/manual/en/language.oop5.php。 - sephoy08
4个回答

7

这取决于你的代码。最简单的情况是如果你没有调用父类构造函数,什么都不会发生,但是如果你的父类构造函数对父类进行了一些初始化操作,则这些操作将被省略。请考虑并尝试以下代码:

<?php

class X {
    private $_a;

    public function __construct($a) {
        echo 'X::construct ';
        $this->_a = $a;
    }

    public function getA() {
        return $this->_a;
    }
}

class Y extends X {
    private $_b;

    public function __construct($a,$b) {
        echo 'Y::construct ';
        parent::__construct($a);
        $this->_b = $b;
    }

    public function getAB() {
        return $this->_b + $this->getA();
    }
}

$n = new Y(3,2);
echo $n->getAB();

很容易看出,如果您运行此代码,它会输出5(以及其他内容)。但是如果您注释掉class Y中的父类调用 parent::__construct($a);,则得到结果为2。这就是在这种情况下的后果。


3
因为如果子类定义了构造函数,则不会自动调用父类构造函数。如果子类假设父类已经初始化并完成了一些工作,则需要确保进入父类构造函数。
例如,您可能扩展了一个类,在其中您不希望调用父类构造函数。这种行为只是在设计上提供了更多的灵活性。在大多数情况下,您可能需要调用父类构造函数。
这完全取决于您扩展父类的原因。您是否需要需要父类初始化的方法?如果是,就调用它的构造函数。您是否可以在扩展之后注入某些特定的依赖项,或者只需要简单的东西,如常量?那么您可能不需要调用父类构造函数。

1

后果实际上取决于父构造函数中发生了什么。所有公共和受保护的成员属性和方法即使没有调用父构造函数也是可用的,这是正确的。但是继承类成员的值可能会在父构造函数中被修改/初始化 - 您需要决定是否希望发生这种情况。

通常情况下,即使什么也没有发生(这可能会在将来发生变化),始终向父构造函数添加调用是一个好决策。唯一省略此调用的原因是当您需要覆盖构造函数中执行的操作时。这是一个比您在Java中拥有的更灵活的功能,那里调用父构造函数是强制性的。


0

PHP手册用非常简单的语言解释了它

注意:如果子类定义了构造函数,则不会隐式调用父类构造函数。为了运行父类构造函数,需要在子类构造函数中调用parent::__construct()。如果子类没有定义构造函数,则可以像普通类方法一样从父类继承(如果它没有被声明为私有)。

https://www.php.net/manual/en/language.oop5.decon.php


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接