web-dev-qa-db-ja.com

派生クラスがインスタンス化されるときに、抽象クラスコンストラクターは暗黙的に呼び出されませんか?

次の例をご覧ください。

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

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

$c = new Child();   

C#のバックグラウンドから来て、出力は

ベース__construct
子供__construct

ただし、実際の出力は

子__construct

61
scottm

いいえ、子クラスがコンストラクターを定義している場合、親クラスのコンストラクターは呼び出されません。

子クラスのコンストラクターから、親のクラスのコンストラクターを呼び出す必要があります。

_parent::__construct();
_

必要に応じて、パラメーターを渡します。

一般に、特定のコードの前に、子クラスのコンストラクターの先頭でこれを行います。つまり、あなたの場合、あなたは持っているだろう:

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


そして、参考として、このページのPHP manual: Constructors and Destructors -it state(引用)

注:子クラスがコンストラクターを定義している場合、親コンストラクターは暗黙的に呼び出されません。
親コンストラクターを実行するには、子コンストラクター内でparent::__construct()を呼び出す必要があります。

104
Pascal MARTIN

まあ、私はちょうどこれを docs で見つけました:

注:子クラスがコンストラクターを定義している場合、親コンストラクターは暗黙的に呼び出されません。親コンストラクターを実行するには、子コンストラクター内でparent :: __ construct()を呼び出す必要があります。

6
scottm

C#と同じ動作が必要な場合、つまり、親コンストラクターが常に子コンストラクターの前に実行される場合、子クラスの偽のコンストラクタークラスを作成し、抽象親クラスの抽象関数として宣言できます。

例えば。

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 */
3
Otamay