在实例化派生类时,是否未隐式调用抽象类构造函数?

时间:2010-02-23 19:21:20

标签: php abstract-class

举个例子:

abstract class Base {
    function __construct() {
        echo 'Base __construct<br/>';
    }
}

class Child extends Base {
    function __construct() {
        echo 'Child __construct<br/>';
    }
}

$c = new Child();   

来自C#背景,我希望输出为

  

Base __construct
Child __construct

然而,实际输出只是

  

儿童__construct

3 个答案:

答案 0 :(得分:102)

不,如果子类定义了构造函数,则不会调用父类的构造函数。

从子类的构造函数中,您必须调用父类的构造函数:

parent::__construct();

如果需要,传递参数。

通常,您将在子类的构造函数的开头,在任何特定代码之前执行此操作;这意味着,在您的情况下,您将拥有:

class Child extends Base {
    function __construct() {
        parent::__construct();
        echo 'Child __construct<br/>';
    }
}


并且,作为参考,您可以查看PHP手册的这一页:Constructors and Destructors - 它声明(引用)

  

注意:如果子类,则不会隐式调用父构造函数   定义构造函数。
为了   运行父构造函数,调用   parent::__construct()内的{{1}}   子构造函数是必需的。

答案 1 :(得分:6)

好吧,我刚刚在docs中找到了这个:

  

注意:父构造函数不是   如果子类隐式调用   定义构造函数。为了运行   父构造函数,调用   子节点中的parent :: __ construct()   构造函数是必需的。

答案 2 :(得分:3)

如果您需要与C#相同的行为,即父构造函数总是在子构造函数之前执行,您可以为子类创建一个伪构造函数类,并在抽象父类中将其声明为抽象函数。

E.g。

abstract class Test{
  abstract public function __childconstruct();
  public function __construct(){
    echo "SOME CODE".PHP_EOL;
    $this->__childconstruct();
  }
}

class TestExtended extends Test{
  public function __childconstruct(){
    echo "SOME OTHER CODE FROM EXTENDED CLASS".PHP_EOL;
  }
}

$a = new TestExtended();

/* SOME CODE
   SOME OTHER CODE FROM EXTENDED CLASS */