Werden abstrakte Klassenkonstruktoren nicht implizit aufgerufen, wenn eine abgeleitete Klasse instanziiert wird?

Lesezeit: 3 Minuten

Nehmen Sie dieses Beispiel:

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

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

$c = new Child();   

Da ich aus einem C # -Hintergrund komme, erwarte ich, dass die Ausgabe lautet

Basis __konstruieren
Kind __konstruieren

Die tatsächliche Ausgabe ist jedoch gerecht

Kind __konstruieren

Nein, der Konstruktor der Elternklasse wird nicht aufgerufen, wenn die Kindklasse einen Konstruktor definiert.

Vom Konstruktor Ihrer untergeordneten Klasse müssen Sie den Konstruktor der übergeordneten Klasse aufrufen:

parent::__construct();

Übergabe von Parametern, falls erforderlich.

Im Allgemeinen tun Sie dies am Anfang des Konstruktors der untergeordneten Klasse, vor einem bestimmten Code ; was bedeutet, in Ihrem Fall hätten Sie:

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

Und als Referenz können Sie sich diese Seite des PHP-Handbuchs ansehen: Konstruktoren und Destruktoren — Es sagt aus (Zitat) :

Notiz: Übergeordnete Konstruktoren werden nicht implizit aufgerufen, wenn die untergeordnete Klasse einen Konstruktor definiert.
Um einen übergeordneten Konstruktor auszuführen, muss ein Aufruf von
parent::__construct() innerhalb des untergeordneten Konstruktors ist erforderlich.

  • Sie geben dies nicht ausdrücklich an, aber sie implizieren, dass, wenn die untergeordnete Klasse keinen Konstruktor hat, der übergeordnete Konstruktor aufgerufen wird. Ist das wahr?

    – Andreas

    9. Februar 2011 um 23:03 Uhr

  • Yes : Wenn die untergeordnete Klasse keinen Konstruktor definiert, wird der der übergeordneten Klasse nicht überschrieben und heißt daher ;;; Zitieren des Handbuchs: Übergeordnete Konstruktoren werden nicht implizit aufgerufen wenn die untergeordnete Klasse einen Konstruktor definiert.

    – Pascal Martin

    10. Februar 2011 um 6:32 Uhr

  • @PascalMARTIN Danke, habe mich umgesehen, um das zu überprüfen. Habe ein bisschen gesucht.

    – Kirill Fuchs

    29. Oktober 2012 um 0:22 Uhr

Nun, ich habe das gerade in der gefunden Dokumente:

Hinweis: Übergeordnete Konstruktoren werden nicht implizit aufgerufen, wenn die untergeordnete Klasse einen Konstruktor definiert. Um einen übergeordneten Konstruktor auszuführen, ist ein Aufruf von parent::__construct() innerhalb des untergeordneten Konstruktors erforderlich.

  • Der Hauptgrund, warum ich einen Konstruktor in einer abstrakten Klasse schreibe, besteht darin, zu erzwingen, dass jede Klasse, die von dieser Klasse erbt, den angegebenen Code ausführt. Es ist wirklich schade, dass PHP die Ausführung des Konstruktors optional macht.

    – Ryan Williams

    30. Juni 2015 um 4:35 Uhr

  • @RyanWilliams Es gibt Fälle, in denen Sie den übergeordneten Konstruktor aufrufen müssen, bevor Sie eine zusätzliche Initialisierung in der Klasse durchführen, und es gibt Fälle, in denen der übergeordnete Konstruktor nach zusätzlichen Initialisierungen aufgerufen wird. Mit PHP können Sie also auch mehr Anwendungsfälle unterstützen.

    – Nux

    13. Oktober 2015 um 9:15 Uhr

Wenn Sie dasselbe Verhalten wie C# benötigen, d. h. der übergeordnete Konstruktor wird immer vor dem untergeordneten Konstruktor ausgeführt, können Sie eine gefälschte Konstruktorklasse für Ihre untergeordneten Klassen erstellen und sie als abstrakte Funktion in Ihrer abstrakten übergeordneten Klasse deklarieren.

Z.B

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

  • Dies löst auch das Problem, wenn Sie untergeordnete Klassen erzwingen müssen, um Aktionen für Konstrukte zu definieren, aber auch um Basisverhalten in übergeordneten Klassen zu definieren (PHP erlaubt keine abstrakten Konstruktoren mit einem Hauptteil {...})

    – jave.web

    12. September 2018 um 1:00 Uhr

1335190cookie-checkWerden abstrakte Klassenkonstruktoren nicht implizit aufgerufen, wenn eine abgeleitete Klasse instanziiert wird?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy