J'apprends PHP et j'ai trouvé un comportement surprenant quand j'essayais de comprendre pourquoi un constructeur n'était pas appelé. Je suis habitué à Java, donc je pensais que cela produirait "Shape, Triangle." Étonnamment, il sort juste "Triangle". J'ai cherché le problème et apparemment je peux un peu le résoudre en mettant parent::__construct();
dans la classe enfant, mais cela ne semble pas idéal. Est-ce que je peux faire quelque chose à la classe Shape pour m'assurer que les classes enfant appellent toujours le constructeur parent? Dois-je vraiment écrire parent::__construct();
dans la classe de chaque enfant chaque fois que le parent a un constructeur?Puis-je forcer une classe enfant à utiliser le constructeur du parent?
Répondre
Si vous définissez une méthode du même nom dans une classe enfant, la méthode du parent est substituée et ne sera en aucun cas appelée, à moins que vous ne le fassiez explicitement. I.e .: Non, il n'y a rien que vous puissiez faire à ce sujet, vous devez appeler parent::__constructor()
explicitement.
+1 rien d'autre à ajouter. – Hamish
Vous pouvez également demander au parent de déclarer une méthode d'initialisation abstraite ou vide que le constructeur parent appelle. – erisco
@erisco Ce serait un bon modèle de conception pour contourner cela, mais cela ne change rien aux faits. :) – deceze
Selon le manuel PHP:
Parent constructors are not called implicitly if the child class defines
a constructor. In order to run a parent constructor, a call to
parent::__construct() within the child constructor is required.
PHP 5, vous pouvez utiliser la final keyword pour empêcher une méthode mère d'être substituée.
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called\n";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called\n";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called\n";
}
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
Vous pouvez utiliser cette en combinaison avec une méthode init()
prédéfini pour assurer votre constructeur parent a été appelé.
<?php
abstract class Shape {
final function __construct() {
$this->init();
echo 'Shape.';
}
abstract public function init();
}
class Triangle extends Shape {
function init() {
echo 'Triangle';
}
}
$tri = new Triangle();
Cette génèrerait
TriangleShape.
Il est conseillé d'utiliser seulement un design comme celui-ci si vous documentez ce que la méthode init()
fait, et où il est appelé dans le parent.
Je suis assez sûr qu'il le faut, sauf si vous ne définissez pas le constructeur enfant. –
duplication possible de [Le constructeur de Superclass s'exécute-t-il dans le constructeur enfant en PHP?] (Http://stackoverflow.com/questions/738571/is-superclasss-constructor-run-inside-child-constructor-in-php) – outis