web-dev-qa-db-fra.com

Les constructeurs de classes abstraites ne sont-ils pas implicitement appelés lorsqu'une classe dérivée est instanciée?

Prenez cet exemple:

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

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

$c = new Child();   

Venant d'un arrière-plan C #, je m'attends à ce que la sortie soit

Base __construct
Enfant __construct

Cependant, la sortie réelle est juste

Enfant __construct

61
scottm

Non, le constructeur de la classe parent n'est pas appelé si la classe enfant définit un constructeur.

Depuis le constructeur de votre classe enfant, vous devez appeler le constructeur de la classe parent:

parent::__construct();

En lui passant des paramètres, si nécessaire.

Généralement, vous le ferez au début du constructeur de la classe enfant, avant tout code spécifique; ce qui signifie, dans votre cas, que vous auriez:

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


Et, pour référence, vous pouvez jeter un œil à cette page du manuel PHP: Constructors and Destructors - it states (citation):

Remarque: Les constructeurs parents ne sont pas appelés implicitement si la classe enfant définit un constructeur.
Pour exécuter un constructeur parent, un appel à parent::__construct() dans le constructeur enfant est requis.

104
Pascal MARTIN

Eh bien, je viens de trouver cela dans le docs :

Remarque: Les constructeurs parents ne sont pas appelés implicitement si la classe enfant définit un constructeur. Pour exécuter un constructeur parent, un appel à parent :: __ construct () dans le constructeur enfant est requis.

6
scottm

Si vous avez besoin du même comportement que C #, c'est-à-dire que le constructeur parent est toujours exécuté avant le constructeur enfant, vous pouvez créer une fausse classe constructeur pour vos classes enfants et la déclarer comme une fonction abstraite dans votre classe parent abstraite.

Par exemple.

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