Jetzt wollen wir unser theoretisches Wissen über Vererbung und Sichtbarkeiten anhand unserer Klasse Raumschiff_fabrik mal in der Praxis anwenden.
Raumschiff_fabrik: Spezialisierung
Neue Kolonisierungsschiffe sind auf dem Weg zu angrenzenden Sonnensystemen, unser Sternenimperium wächst und der Handel zwischen den Planeten steigt. Jetzt ist es an der Zeit unsere Flotte zu spezialisieren.
Bislang wirft unsere Raumschifffabrik nur einen Typ Raumschiff aus. Doch damit unsere Zivilisation wächst und gedeiht brauchen wir Transporter (für den Handel), Scouts (entdeckt feindliche Raumschiffe, findet kolonisierbare Planeten), Fighter (kleine, bewaffnete Raumschiffe), und Zerstörer (das Kernstück unserer Abschreckungsflotte).
Bevor wir unsere Raumschifffabrik erweitern, hier nochmal der bisherige Stand der Klasse Raumschiff_fabrik:
<?php //dieser Quellcode kommt nun in die Datei "Raumschiff_fabrik.php" class Raumschiff_fabrik { protected $geschwindigkeit = 5; protected $schild = 3; protected $leben = 10; protected $typ; protected $name; public function __construct($neuer_name = null) { if($neuer_name != null) $this->name = $neuer_name; else $this->name = 'Raumschiff-ID#'.rand(999, 99999); } protected function treffer($schaden) { if($this->schild < $schaden) { //berechne wieviel Schaden trotz des Schilds entsteht $rest_schaden = $schaden - $this->schild; $this->leben -= $rest_schaden; if($this->leben <= 0) { echo 'Raumschiff "'.$this->name.'" wurde zerstört'; } } } } ?>
Lege nun eine neue Datei mit Namen Raumschiff_fabrik.php an und packe obigen Quellcode in diese Datei. Wie dir wahrscheinlich aufgefallen ist, habe ich einige Änderungen vorgenommen. Alle Eigenschaften sind nun „protected„, da ich nicht möchte, dass die Werte der Eigenschaften direkt über das Objekt verändert werden können. Allerdings möchte ich, dass unsere spezialisierten Raumschiffe auf die gleichen Eigenschaften zugreifen können (deshalb nicht „private„).
Zusätzlich habe ich noch eine Eigenschaft „typ“ hinzugefügt, die in der nächsten Klasse einen Wert erhalten wird.
Spezialklasse: Fighter
Lege im gleichen Ordner, indem auch die Datei Raumschiff_fabrik.php liegt eine neue Datei Fighter.php an. Dies ist eine spezialisierte Klasse, die von der Klasse „Raumschiff_fabrik“ erbt:
<?php require_once('Raumschiff_fabrik.php'); class Fighter extends Raumschiff_fabrik { protected $geschwindigkeit = 7; protected $schild = 5; protected $leben = 20; protected $laser = 8; public function __construct() { // rufe den Konstruktor der Klasse Raumschiff_fabrik auf parent::__construct(); $this->typ = __Class__; //alternative Schreibweise: $this->typ = 'Fighter'; } protected function attack() { return $this->laser; } } //nur zum testen, soll nicht mit in der Datei stehen $fighter1 = new Fighter; print_r($fighter1); ?>
Erklärung:
Als erstes binden wir die Klasse „Raumschiff_fabrik“ mittels „require_once“ in unser Skript ein. Dies ist nötig damit die Klasse „Fighter“ von der Klasse „Raumschiff_fabrik“ vererbt werden kann (Zeile 4 „extends“). Als nächstes erhöhen wir die Werte „Geschwindigkeit“, „Schild“ und „Leben“ um unsere Kampfflieger ein bisschen widerstandsfähiger zu machen. Zusätzlich geben wir der Klasse „Fighter“ noch die Eigenschaft „laser“. Wenn unser Fighter-Objekt angreift, kann es pro Attacke 8 Schaden zufügen.
Der Konstruktor ist neu:
public function __construct() { // rufe den Konstruktor der Klasse Raumschiff_fabrik auf parent::__construct(); $this->typ = __Class__; //alternative Schreibweise: $this->typ = 'Fighter'; }
Wir möchten, dass unser Fighter-Konstruktor genau das gleiche macht wie der Konstruktor der Klasse „Raumschiff_fabrik“ doch zusätzlich noch der Eigenschaft „typ“ den Typ des Raumschiffs zuweist. Wenn wir lediglich eine neue Methode „__constuct()“ anlegen, wird der Konstruktor der Elternklasse überschrieben und die Funktionalität geht verloren. Daher nutzen wir:
parent::__construct();
Damit rufen wir die Funktionalität der Methode „__construct“ der Elternklasse auf. Das Schlüsselwort „parent“ können wir auch in anderen Methoden verwenden um auf die Funktionalität einer bestimmten Methode der Elternklasse zuzugreifen. Nun weisen wir der Eigenschaft „typ“ noch einen Wert zu. Jedes spezialisierte Objekt soll ihren Typ mit aufnehmen (sprich: Objekte der Klasse Fighter, sollen den Typ „Fighter“ haben). Dies können wir auf zwei Arten machen:
$this->typ = 'Fighter'; $this->typ = __Class__;
Standardmäßig wird man hier einfach einen String übergeben. In Zeile 3 möchte ich euch aber mal an einem Beispiel zeigen, wie man magische Konstanten verwenden kann. Die magische Konstante __Class__ beinhaltet den Namen der Klasse in der wir uns gerade befinden („Fighter“).
Als letztes erhält die Klasse „Fighter“ eine Methode „angriff“. Wenn ein Fighter-Objekt ein feindliches Raumschiff angreift, gibt diese Methode den erzeugten Schaden aus (Stärke des Lasers).
Die weiteren Raumschiff-Typen (Scout, Transporter und Zerstörer) werden in den Unterartikeln angelegt und erklärt.