Werden in der Objektorientierten Programmierung in einer Elternklasse Konstruktoren und
Destruktoren verwendet, sind bei der Vererbung einige Detailpunkte zu beachten. Zu diesen Punkten zählt unter anderem, dass die
Sichtbarkeit der Konstruktor- und Destruktormethoden in der Elternklasse nicht eingeschränkt werden darf, insofern in einer
von der Elternklasse abgeleiteten Klasse keine eigenen Konstruktor- und Destruktormethoden verwendet werden. So würde zum
Beispiel die Verwendung des Schlüsselwortes protected beim Definieren eines Konstruktors oder eines Destruktors im
nachfolgenden Exempel einen Fehler auslösen.
Erstes Beispiel Vererbung (klasse-09a.php):
<?php class GesellenKlasse { protected $abgabe = "Maurer"; protected $zugabe = "Betonbauer"; protected $rueckgabe; public function __construct() { $this->rueckgabe = "Ergebnis für ".$this->abgabe." und ".$this->zugabe."<br>\n"; } public function __destruct() { echo "Destructor: Maurer und ".$this->zugabe; } } class LehrlingsKlasse extends GesellenKlasse { public function mitMethode() { return $this->rueckgabe; } } $obj = new LehrlingsKlasse(); echo $obj->mitMethode()."\n"; /* Ausgabe: Ergebnis für Maurer und Betonbauer Destructor: Maurer und Betonbauer */ ?>
Im Beispiel werden in der Gesellenklasse ein Konstruktor und ein Destruktor verwendet, ein Objekt wird
hingegen aus der abgeleiteten Klasse der Lehrlinge erzeugt. Diese Kinderklasse erbt von der Elternklasse alle Eigenschaften und
Methoden und ruft dabei die Konstruktor- und Destruktormethode der Gesellenklasse auf. Würde die Sichtbarkeit einer oder
beider Methoden durch die Verwendung des Schlüsselwortes protected eingeschränkt, wäre eine Error-Mitteilung die Folge.
Der Fehler hängt in dieser Konstellation damit zusammen, dass die Methoden __construct() und __destruct() praktisch keinen
Rückgabewert liefern, der mit dem Sprachkonstrukt return zurück an eine Methode oder an eine Eigenschaft gegeben werden
könnte.
Etwas anders sieht es beim zweiten Beispiel aus. Die abgeleitete Klasse der Kinder benutzt ebenfalls die Magischen Methoden
__construct() und __destruct() und würde nur ihre eigene Methoden verwenden, wenn die Konstruktor- und Destruktormethoden der
Elternklasse nicht ausdrücklich durch die Verwendung des Schlüsselwortes parent, gefolgt von einem doppelten Doppelpunkt, mit
aufgerufen werden. Dadurch, dass die Methoden __construct() und __destruct() der Kinderklasse nicht in der Sichtbarkeit
eingeschränkt sind, ergibt die Einschränkung der Sichtbarkeit innerhalb der Elternklasse keinen Fehler.
Zweites Beispiel Vererbung (klasse-09b.php):
<?php class ElternKlasse { protected $abgabe = "Tischler"; protected $zugabe = "Schneider"; public $rueckgabe; protected function __construct() { $this->abgabe = "Ergebnis für ".$this->abgabe; } protected function __destruct() { echo "Destructor Schneider"; } } class KinderKlasse extends ElternKlasse { public function __construct() { parent::__construct(); $this->rueckgabe = $this->abgabe." und ".$this->zugabe."<br>\n"; } public function __destruct() { parent::__destruct(); echo " und Destructor Tischler<br>\n"; } } $obj = new KinderKlasse(); echo $obj->rueckgabe."\n"; /* Ausgabe: Ergebnis für Tischler und Schneider Destructor Schneider und Destructor Tischler */ ?>
Ergänzend sei vermerkt, beim doppelten Doppelpunkt handelt es sich um einen
Gültigkeitsbereichsoperator. Erwähnenswert ist weiterhin, wird für eine Methode einer Klasse der derselbe Bezeichner wie für
die Klasse verwendet, wird diese Methode ebenfalls wie ein Konstruktor ausgewertet.
Nicht vergessen werden sollte bei der Auswahl von geeigneten Bezeichnern, dass PHP bei den Bezeichnern von Klassen und Methoden
nicht zwischen Groß- und Kleinschreibung unterscheidet und so wird aus zwei Bezeichnern, die sich nur in der Groß- und
Kleinschreibung unterscheiden (wie im folgenden Beispiel die Bezeichner "Berufe" und "berufe"), ein
und derselbe Bezeichner. Teilen sich zum Beispiel eine Elternklasse und eine in dieser Klasse definierte Methode einen
Bezeichner, so ist eine Notierung der Magischen Methode __construct() in der Elternklasse nicht erforderlich, um mit parent::
auf diesen Konstruktor von einer abgeleiteten Klasse aus zuzugreifen.
Ein Beispiel mit gleichnamigen Bezeichnern (klasse-10a.php):
<?php class Berufe { protected $beruf = "Zimmermann"; protected function berufe() { echo "Ergebnis für ".$this->beruf."\n"; } } class Handwerker extends Berufe { public function __construct() { parent::__construct(); } } $obj = new Handwerker(); /* Ausgabe: Ergebnis für Zimmermann */
Ein weitestgehend identischer Code, jedoch mit sich unterscheidenden Bezeichnern, würde hingegen
nur einen fatalen Fehler auslösen.
Ein Beispiel mit sich unterscheidenden Bezeichnern (klasse-10b.php):
?> <?php class BerufsKlasse { protected $beruf = "Kellner"; protected function setzeBeruf() { echo "Ergebnis für ".$this->beruf."\n"; } } class DienstBoten extends BerufsKlasse { public function __construct() { parent::__construct(); } } $obj = new DienstBoten(); /* Ausgabe: Fatal error: Cannot call constructor in ... */ ?>
Dass aus einer Methode ein Konstruktor wird, kann gewollt sein oder auf einen Fehler bei der Wahl eines geeigneten Bezeichners beruhen. Einen Konstruktor als Magische Methode mit __construct() zu notieren, beugt zumindest unabsichtlichen Fehlern vor.
Konstruktoren und Destruktoren « zurück
Einstieg in PHP
Übersicht
Diverse Themen