Vererbung

Vererbung erlaubt es, bestehenden Code zu erweitern, ohne ihn ändern oder duplizieren zu müssen. PHP unterstützt hierbei die klassenbasierte Einfachvererbung, bei der eine so genannte Kindklasse sämtliche als public und protected deklarierten Instanzvariablen und Methoden von ihrer Elternklasse übernimmt (erbt) [4] . Die Kindklasse kann diese überschreiben sowie neue Instanzvariablen und Methoden definieren.

Die Vererbungsbeziehung einer Kindklasse zu ihrer Elternklasse wird durch das extends-Schlüsselwort in der Klassendeklaration ausgedrückt. Eine Klasse hat in PHP maximal eine Elternklasse, sie kann jedoch beliebig viele Kindklassen besitzen.

Mit dem Schlüsselwort final markierte Methoden der Elternklasse können in der Kindklasse nicht redefiniert werden, als final markierte Klassen können per Vererbung nicht erweitert werden.

Betrachten wir als Beispiel die Erweiterung der Klasse DB_MySQL um die Serverkonfiguration für ein spezielles Projekt. Hierzu müssen wir lediglich eine Klasse MyProject_DB als Kindklasse von DB_MySQL einführen, deren Konstruktor wir dann entsprechend redefinieren. Abbildung 1.2 zeigt ein entsprechendes UML-Klassendiagramm. Der Pfeil symbolisiert die Vererbung, die Kindklasse zeigt auf ihre Elternklasse.

Abbildung 1.2. Für ein Projekt spezialisierte, von DB_MySQL abgeleitete Klasse

Für ein Projekt spezialisierte, von DB_MySQL abgeleitete Klasse


Beispiel 1.18: Für ein Projekt spezialisierte, von DB_MySQL abgeleitete Klasse

<?php
require_once 'DB_MySQL.php';
 
class MyProject_DB extends DB_MySQL {
  const DB_HOST     = 'localhost';
  const DB_DATABASE = 'test';
  const DB_USER     = 'root';
  const DB_PASS     = '';
 
  public function __construct($query = '') {
    $this->connect(
      self::DB_HOST,
      self::DB_DATABASE,
      self::DB_USER,
      self::DB_PASS
    );
 
    if (!empty($query)) {
      $this->query($query);
    }
  }
}
?>


Durch die Möglichkeit, dem Konstruktor von MyProject_DB eine SQL-Anfrage zu übergeben, reduziert sich der vom Verwender der Klasse zu schreibende Code auf ein Minimum. Beispiel 1.19 zeigt, wie die abgeleitete Klasse den wiederkehrenden Code für SQL-Anfragen und die Verarbeitung ihrer Ergebniszeilen auf ein Minimum reduziert. Und sollten sich die Zugangsdaten für den MySQL-Server ändern, so müssen diese nur an einer Stelle aktualisiert werden. Dies erhöht zusätzlich die Wartbarkeit des Codes.

Beispiel 1.19: Verwendung der abgeleiteten Klasse

<?php
require_once 'MyProject_DB.php';
 
$db = new MyProject_DB('SELECT spalte FROM tabelle');
 
while ($row = $db->fetchRow()) {
  // ...
}
?>


Wird in einer abgeleiteten Klasse keine Konstruktor- beziehungsweise Destruktor-Methode deklariert, so wird implizit die entsprechende Methode der Elternklasse aufgerufen. Andernfalls wird die Methode der Kindklasse aufgerufen, ohne dass die entsprechende Methode der Elternklasse implizit aufgerufen wird. Diese kann bei Bedarf jedoch explizit über parent::__construct() beziehungsweise parent::__destruct() aufgerufen werden.

Beispiel 1.20: Verhalten von Konstruktor- und Destruktormethode in abgeleiteten Klassen

<?php
class Elternklasse {
  public function __construct() {
    print "Elternklasse::__construct() aufgerufen.\n";
  }
 
  public function __destruct() {
    print "Elternklasse::__destruct() aufgerufen.\n";
  }
}
 
class Kindklasse extends Elternklasse {
  public function __construct() {
    parent::__construct();
    print "Kindklasse::__construct() aufgerufen.\n";
  }
}
 
$objekt = new Kindklasse;
?>
Elternklasse::__construct() aufgerufen.
Kindklasse::__construct() aufgerufen.
Elternklasse::__destruct() aufgerufen.





[4] Man sagt auch, dass die Kindklasse von der Elternklasse abgeleitet wird und nennt die Kindklasse auch abgeleitete Klasse.