Vererbung

Vererbung ist ein wichtiges Hilfsmittel in der objektorientierten Programmierung. Man kann Klassen von Klassen ableiten und erbt so alle Methoden oder Eigenschaften. Folgendes Beispiel soll das mal verdeutlichen:

class BallKlasse {
	public $farbe;
	public $groesse;
	protected $preis;
	
	public function anmalen($farbe) {
		$this->farbe = $farbe;
	}
	
	public function aufpumpen($luftmenge) {
		$this->groesse = $luftmenge;
	}
	
	public function beschreibe () {
		$beschreibung = "Die Farbe ist ".$this->farbe."\n";
		$beschreibung .= "Die Groesse ist ".$this->groesse."\n";
		$beschreibung .= "Der Preis ist ".$this->preis."\n";
		return $beschreibung;
	}
	
	protected function preisaendern() {
		$this->preis++;
	}
}

class BallShop extends BallKlasse {
	
	public function treibepreis() {
		$this->preisaendern();
	}
	
}

$shop = new BallShop();
$shop->treibepreis();
$shop->treibepreis();
$shop->anmalen("weiss");
$shop->aufpumpen(1);

echo $shop->beschreibe();
// Die Farbe ist weiss
// Die Groesse ist 1
// Der Preis ist 2

Wow, was haben wir denn jetzt gemacht? Naja, zunächst einmal haben wir eine Klasse mittels extends abgeleitet. Ich habe ja schon gesagt, dass in einem Objekt alle Methoden und Eigenschaften enthalten sind. Das gilt natürlich auch für abgeleitete Klassen, die auch als Kindklassen bezeichnet werden. Wenn man also eine Kindklasse von einer Elternklasse ableitet, so werden alle Eigenschaften und Methoden geerbt. In diesem Fall erben wir unter anderem die protected Methode preisaendern() und greifen auf sie mittels einer public Methode treibepreis() zu. Coole Sache :). Aber das funktioniert nur bei protected Methoden oder Eigenschaften. Mittels private deklarierte Methoden oder Eigenschaften sind komplett geschützt und können auch so nicht verändert oder benutzt werden.

 

Aber kann man nur von Eltern auf Kindklassen ableiten, oder geht das auch von einer Großelternklasse? Folgendes Beispiel zeigt die Möglichkeiten einer Ableitung:

class Grosseltern {
	protected $alter;
	protected $augenfarbe = "braun";
	protected $haarfarbe;
	protected $beruf;
	
	public function setalter($alter) {
		$this->alter = $alter;
	}
}

class Eltern extends Grosseltern {

	public function setaugenfarbe($augenfarbe) {
		$this->augenfarbe = $augenfarbe;
	}
	
	public function sethaarfarbe($haarfarbe) {
		$this->haarfarbe = $haarfarbe;
	}
	
	protected function setjob($job) {
		$this->beruf = $job;
	}
}

class Kinder extends Eltern {
	
	public function setberuf($beruf) {
		$this->setjob($beruf);
	}
	
	public function geteigenschaften() {
		$values = "Das Alter ist ".$this->alter. " Jahre\n";
		$values .= "Die Augenfarbe ist ".$this->augenfarbe."\n";
		$values .= "Die Haarfarbe ist ".$this->haarfarbe."\n";
		$values .= "Der Beruf ist ".$this->beruf."\n";
		
		return $values;
	}
}

$kind = new Kinder;
$kind->setalter(46);
$kind->sethaarfarbe("braun");
$kind->setberuf("Psychologe");

echo $kind->geteigenschaften();
// Das Alter ist 46Jahre
// Die Augenfarbe ist braun
// Die Haarfarbe ist braun
// Der Beruf ist Psychologe

Na Klasse, was haben wir in dem Beispiel gemacht?

  1. Von der Großelternlasse haben wir setalter() geerbt.
  2. Von der Elternklasse haben wir setaugenfarbe(), sethaarfarbe() und setjob() geerbt, können aber als direkten Aufruf und die public-Methoden verwenden. Für die protected-Methode setjob benutzen wir dann die public-Methode setberuf().
  3. Die Augenfarbe haben wir überhaupt nicht geändert, die haben wir direkt aus der Großelternklasse übernommen.

 

Ok, es gibt auch noch mehrere Möglichkeiten, Methoden oder Eigenschaften zu manipulieren, z.B. durch Überschreiben. Folgendes Beispiel:

class BallKlasse {
	public $farbe;
	public $groesse;
	protected $preis;
	
	public function anmalen($farbe) {
		$this->farbe = $farbe;
	}
	
	public function aufpumpen($luftmenge) {
		$this->groesse = $luftmenge;
	}
	
	public function beschreibe () {
		$beschreibung = "Die Farbe ist ".$this->farbe."\n";
		$beschreibung .= "Die Groesse ist ".$this->groesse."\n";
		$beschreibung .= "Der Preis ist ".$this->preis."\n";
		return $beschreibung;
	}
	
	protected function preisaendern() {
		$this->preis++;
	}
}

class BallShop extends BallKlasse {
	
// 	Das wuerde einen ueblen Fehler geben
//	da sich die Methode selbst aufruft
//	public function preisaendern() {
//		$this->preisaendern();
//	}

	public function preisaendern() {
		parent::preisaendern();
	}
	
}

$shop = new BallShop();
$shop->preisaendern();
$shop->preisaendern();
$shop->anmalen("weiss");
$shop->aufpumpen(1);
echo $shop->beschreibe();
//	Die Farbe ist weiss
//	Die Groesse ist 1
//	Der Preis ist 2

Wir haben jetzt ein fast identisches Beispiel zum obigen Code benutzt, das jedoch leicht abgeändert. In der Klasse BallShop haben wir die Methode treibeepreis() umgeändert in die Methode preisaendern(). Diese Methode gibt es ja schon in der Elternklasse BallKlasse. Um sie aufzurufen, benutzten wir jetzt den doppelten Doppelpunkt mit dem Wörtchen parent davor. Auf diese Weise können wir Eigenschaften oder Methoden aus Elternklassen benutzten und überschreiben.