PHP-Einfach.de
  • PHP Tutorial
  • MySQL Tutorial
  • Für Fortgeschrittene
  • Webhosting
  • Jobs
  • Forum

Vererbung

10. Februar 2020
  1. Home
  2. »
  3. Für Fortgeschrittene
  4. »
  5. Objektorientierte Programmierung
  6. »
  7. Vererbung

Vererbung ist ein gängiges Prinzip in der Programmierung und PHP unterstützt dieses ebenfalls. Mittels Vererbung könnt ihr verschiedene Hierarchiestufen in euren Klassen ermöglichen. Funktionen die in einer Oberklasse programmiert wurden, vererben sich auf die Unterklassen und können dort verwendet werden.

Inhaltsverzeichnis

  • 1 Vererbung in 30 Sekunden
  • 2 Vererbung ausführlich erläutert
  • 3 Zugriff und Überschreibung von Eigenschaften und Methoden
  • 4 Vererbung über mehrere Generationen
  • 5 Das richtige Klassendesign

Vererbung in 30 Sekunden

Um von einer Klasse zu erben, existiert in PHP das Schlüsselwort extends :

<?php
class Oberklasse {
	function HelloWorld() {
		echo "Hello World <br>";	
	}
}

class Unterklasse extends Oberklasse {
	function HelloWorld() {
		parent::HelloWorld();
		echo "Hallo Welt <br>";				
	}
}

class Unterunterklasse extends Unterklasse {
	function HelloWorld() {
		echo "Bonjour monde <br>";	
	}
}

$object = new Unterklasse();
$object->HelloWorld();
?>

Im obigen Beispiel haben wir eine Oberklasse, dann eine Unterklasse die von der Oberklasse erbt und eine Unterunterklasse, die mittels extends von der Unterklasse erbt.

In alle drei Klassen ist die Methode HelloWorld() definiert, die sich jeweils überschreiben. Möchte man die selbe Methode in der Eltern-Klasse aufrufen, so geht dies mittels parent::HelloWorld() .

Vererbung ausführlich erläutert

Wem die vorherige Anleitung zu knapp war, der freut sich hoffentlich über das nachfolgende, längere Beispiel. Angenommen wir haben einen Online-Shop indem wir verschiedene Produktegruppen anbieten, beispielsweise Bücher, Filme, und CDs. Jede dieser Produktgruppen ist als eigene Klasse definiert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
class Buch {
public $titel;
public $preis;
public $autor;
function gesamtpreis($stueckzahl) {
return $preis*$stueckzahl;
}
}
 
class Film {
public $titel;
public $preis;
public $regisseur;
function gesamtpreis($stueckzahl) {
return $preis*$stueckzahl;
}
}
 
class CD {
public $titel;
public $preis;
public $band;
function gesamtpreis($stueckzahl) {
return $preis*$stueckzahl;
}
}
?>

Wie ihr erahnen könnt, führt solch eine Klassenkonstruktion zu sehr viel redundantem Programmcode. Für Bücher, Filme als auch Musik haben wir die Eigenschaften Titel und Preis sowie eine Methode gesamtpreis($stueckzahl), dennoch müssen wir diese für alle drei Produktgruppen neu implementieren. Schlimmer noch, ändert sich unser Preissystem, z.B. möchten wir ab 10 bestellten Artikeln einen Rabatt von 20% einräumen, müssten wir in allen drei Klassen den Code für die Methode gesamtpreis() anpassen.

Um diesen Code zu vereinfachen, empfiehlt es sich eine Elternklasse zu definieren, die alle ähnlichen Funktionalitäten vereint:

<?php
class Produkt {
	public $titel;
	public $preis;
	
	function gesamtpreis($stueckzahl) {
		$gesamtpreis = $this->preis*$stueckzahl;
		
		if($stueckzahl >= 10) {
			$gesamtpreis = $gesamtpreis*0.8;
		}
		return $gesamtpreis;
	}
}

class Buch extends Produkt {
	public $autor;
}

class Film extends Produkt {
	public $regisseur;
}

class CD extends Produkt {
	public $band;
}

$buch = new Buch();
$buch->titel = "PHP lernen leicht gemacht";
$buch->preis = 20.00;
$menge = 5;
echo  "$menge Bücher von <i>$buch->titel</i> je $buch->preis Euro  kosten: ".$buch->gesamtpreis($menge)."<br>";

$film = new Film();
$film->titel = "Zurück in die Zukunft";
$film->preis = 10.00;
$menge = 15;
echo  "$menge Filme von <i>$film->titel</i> je $film->preis Euro kosten: ".$film->gesamtpreis($menge)." Euro<br>";
?>

Hier haben wir zuerst die Hauptklasse Produkt definiert. Jeder unserer Artikel hat einen Titel sowie einen Preis. Ebenfalls haben wir in der Hauptklasse die Methode gesamtpreis() definiert, die den Gesamtpreis berechnet falls der Kunde eine gewisse Anzahl bestellt. Bestellt dieser 10 oder mehr Artikel, erhält dieser 20% Rabatt auf den Artikel.

Weiter haben wir nun die drei Klassen Buch, Film und CD definiert, die mittels extends von der Klasse Produkt alle public und protected Eigenschaften erben (siehe Sichtbarkeit in OOP). Somit es es nicht mehr nötig in diesen Klassen erneut die selben Eigenschaften oder Methoden zu programmieren, sondern diese werden von der Elternklasse (hier Produkt) übernommen. Ändert ihr den Code der Methode gesamtpreis(), so müsst ihr dies im obigen Fall nur an einer einzigen Stelle machen und nicht mehr wie zuvor an drei verschiedenen Positionen in eurem Code.

Zugriff und Überschreibung von Eigenschaften und Methoden

Nun wollen wir das obige Beispiel erweitern und der Rabatt soll abhängig von der Produktgruppe sein. Für Bücher wollen wir ab einer Stückzahl von 10 einen Rabatt von 20% einräumen, für Filme einen Rabatt von 5% ab zwei Filmen und für CDs gibt es keinen Rabatt. Der aktualisierte Code könnte so aussehen:

<?php
class Produkt {
	public $titel;
	public $preis;
	
	function gesamtpreis($stueckzahl) {
		$gesamtpreis = $this->preis*$stueckzahl*$this->mengenrabatt($stueckzahl);
		return $gesamtpreis;
	}
	
	function mengenrabatt($stueckzahl) {
		return 1;
	}
}

class Buch extends Produkt {
	public $autor;
	
	function mengenrabatt($stueckzahl) {
		if($stueckzahl >= 10) {
			return 0.8; //20% Rabatt
		} else {
			return 1;
		}
	}
}

class Film extends Produkt {
	public $regisseur;
	
	function mengenrabatt($stueckzahl) {
		if($stueckzahl >= 2) {
			return 0.95; //5% Rabatt
		} else {
			return 1;
		}
	}
}

class CD extends Produkt {
	public $band;
}

$buch = new Buch();
$buch->titel = "PHP lernen leicht gemacht";
$buch->preis = 20.00;
$menge = 5;
echo  "$menge Bücher von <i>$buch->titel</i> je $buch->preis Euro  kosten: ".$buch->gesamtpreis($menge)."<br>";

$film = new Film();
$film->titel = "Zurück in die Zukunft";
$film->preis = 10.00;
$menge = 15;
echo  "$menge Filme von <i>$film->titel</i> je $film->preis Euro kosten: ".$film->gesamtpreis($menge)." Euro<br>";
?>

In userer Hauptklasse Produkt fügen wir die Methode mengenrabatt() ein. Standardmäßig existiert kein Rabatt, deswegen gibt die Funktion den Wert 1 zurück.

Diese Methode überschreiben wir in der Klasse Buch. Statt dem Standardverhalten aus der Elternklasse, möchten wir dort ein neues Verhalten festlegen. Falls mehr als 10 Bücher bestellt sind, wird ein Rabatt von 20% gewährt (d.h. der Preis wird mit 0.8 multipliziert). In der Film-Klasse machen wir das selbe, nur dass es dort 5% Rabatt ab 2 Filmen gibt.

Ruft ihr nun für das Objekt die Methode gesamtpreis() auf, so nutzt diese stets die "neueste" Definition von mengenrabatt(), also die Definition, die am tiefsten in der Hierarchie ist. In diesem Fall wird für Objekte der Klassen Buch und Film die entsprechende Methode in diesen Klassen genutzt. Für Objekte der Klasse CD wird dagegen bei Aufruf der Methode mengenrabatt() die Methode aus Produkt verwendet, da wir in CD selbst die Methode nicht neu definiert haben / nicht überschrieben haben.

 

Vererbung über mehrere Generationen

Wie eingangs schon angedeutet, lassen sich Klassen auch über mehrere Generationen vererben. Beispielsweise wollen wir unterscheiden zwischen realen, physikalischen Gegenständen, wie beispielsweise einem Buch, und digitalen Gegenständen wie ein eBook oder ein Video-Stream. Eine mögliche Klassenstruktur könnte so aussehen:

<?php
class Produkt {
	public $titel;
	public $preis;
	
	function gesamtpreis($stueckzahl) {
		$gesamtpreis = $this->preis*$stueckzahl*$this->mengenrabatt($stueckzahl);
		return $gesamtpreis;
	}
	
	function mengenrabatt($stueckzahl) {
		return 1;
	}
}

class RealesProdukt extends Produkt {
	public $lagerbestand;
	
	function istVorraetig() {
		//Überprüfen ob Produkt im Lager vorhanden ist
		return $this->lagerbestand> 0;
	}
}

class Buch extends RealesProdukt {
	public $autor;
}

//------------------------

class DigitalesProdukt extends Produkt {
	public $downloadlink;
}

class eBook extends DigitalesProdukt {
	public $dateiformat;
}

$buch = new Buch();
$buch->lagerbestand = "17";
if($buch->istVorraetig()) {
   echo "Das Buch ist vorrätig<br>";
} else {
   echo "Kein Buch mehr im Lager<br>";
}

$eBook = new eBook();
$eBook->downloadlink = "htttp://website.de";
echo "Der Downloadlink ist: ".$eBook->downloadlink;

Bei Objekten der Klasse Buch können wir auf alle (public und protected) Methoden und Eigenschaften aus den Klassen Buch, RealesProdukt und Produkt zugreifen. Bei der Klasse eBook dagegen können wir auf die Methoden und Eigenschaften der Klassen eBook, DigitalesProdukt und Produkt zugreifen.

Das richtige Klassendesign

Wie man seine Klassen konstruiert, wie viele Haupt- und wie viele Kinderklassen man definiert ist nicht leicht zu entscheiden. Für den Anfang solltet ihr aber versuchen, eure Klassendesign nicht zu kompliziert zu gestalten, ansonsten verliert man schnell den Überblick.

Neben entsprechender Übung empfiehlt es sich auch, ein sogenanntes Klassendiagramm zu zeichnen. In diesem Diagramm zeichnet ihr alle Klassen und deren Beziehungen zueinander ein. Dies hilft um den Überblick zu behalten.

Autor: Nils Reimers
Zurück: Statische Methoden und Eigenschaften
Weiter: PHP Design Patterns

Für Fortgeschrittene

  • Objektorientierte Programmierung
    • Referenzierung in OOP
    • Sichtbarkeit in OOP
    • Methoden und Konstruktoren
    • Statische Methoden und Eigenschaften
    • Vererbung
    • Design Patterns
  • PHP Sicherheit
  • Script-Beispiele
  • Codeschnipsel
  • Stellenmarkt
Mit freundlicher Unterstützung von:
  • Punkt191 Werbeagentur
  • Casinopilot24.com
  • Casino utan Spelpaus
  • Casino utan Spelpaus med Trustly
  • Neueonline-Casinos.com
  • CasinoHEX.at
  • Decasinos.de
  • Privatkredit247.com
  • CasinoAdvisers.com
  • parhaatuudetkasinot.com
  • BitcoinBuster.com
  • CryptoCasinos.com

Hoster – Geringste Ausfallzeit

  1. webgo Ø 1 Min.
  2. netcup Ø 6 Min.
  3. Linevast Ø 7 Min.
  4. manitu Ø 13 Min.
  5. Mittwald Ø 14 Min.
  6. dogado Ø 15 Min.
  7. All-Inkl.com Ø 18 Min.
  8. Hetzner Ø 20 Min.
  9. bplaced Ø 20 Min.
  10. Host Europe Ø 20 Min.
» Mehr erfahren

Impressum | Datenschutz | Auf PHP-Einfach.de werben

© PHP-Einfach.de 2003 - 2021

Um dich beim Lernen von PHP und MySQL zu unterstützen verwenden wir Cookies. OK Weitere Infos
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Notwendige
immer aktiv

Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.

Nicht notwendige

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.