Grundzüge der Programmierung Wiederverwendung VERERBUNG Inhalt dieser Einheit Syntax: Vererbung in Java • Superklassen - Subklassen • Konstruktorenaufruf in Subklassen • super, abstract und final Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 2 Code-Reuse (Wh.) • Einbinden von bereits (selbst-/fremd) programmiertem Code • Wiederverwendung von Klassen, ohne deren Implementierung zu kennen • Varianten – Vorhandenen Klassen verwenden – Vererbung (Klassen erweitern und spezialisieren) Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 3 Vererbung (Wh.) • Vererbung bedeutet, dass eine Klasse B (Subklasse) über die Eigenschaften und das Verhalten einer Klasse A (Superklasse) verfügen kann. • Die Klasse B (Subklasse) kann das geerbte Verhalten redefinieren und/oder um zusätzliche Attribute und Operationen erweitern. • Bezeichnungen für allgemeinere Klassen: Basisklasse, Superklasse oder Generalisierung. • Bezeichnung für speziellere Klassen: abgeleitete Klasse, Subklasse oder Spezialisierung Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 4 Vererbung in Java Syntax: class ClassName extends Superclass { Variablendefinition Methodendefinition } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 5 Klassenhierarchie Bsp. Lebewesen Lebewesen Superklasse -name -alter +laufen() +schlafen() +essen() Subklasse Person Hund -beruf -rasse +essen() +sprechen() +radfahren() +essen() +bellen() Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 6 Superklasse Lebewesen Die Gemeinsamkeiten aller Lebewesen werden in der Superklasse Lebewesen beschrieben. public class Lebewesen { protected String name; protected int alter; Lebewesen (int age, String name){...} public void schlafen() {...} public void essen() {...} } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 7 Subklasse Person Die Spezialisierung erfolgt durch Implementierung der zusätzlichen Eigenschaften und Methoden sowie durch Überschreiben der Methoden. public class Person extends Lebewesen { protected String beruf; //neue Variable Person (){...} public void essen(){...} //überschreiben public void radfahren(){...} //neue Methode } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 8 Subklasse Hund Implementierung der Klasse Hund. public class Hund extends Lebewesen { protected String rasse; //neue Variable Hund (){...} public void essen(){...} //überschrieben public void bellen(){...} //neue Methode } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 9 Zugriffskontrolle • Standardeinstellung: package • Normale Einschränkungen: – public - das Interface der Klasse – private - versteckt, nur von der Klasse verwendbar; bei Vererbung für die Subklasse auch nicht sichtbar! • Zusätzliche Einschränkungen bei Vererbung: – protected - wie package, für alle Subklassen (auch aus anderen Packeten) aber sichtbar und überladbar! Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 10 Fehlerquellen • Überschreiben: Methoden werden durch Methoden mit den gleichen Namen und Parametern in der abgeleiteten Klasse überschrieben. Die alten Methoden werden ersetzt! • Überladen: Unterscheidet sich die neue Methode durch die Art/Anzahl der Parametern wird sie nur überladen. Die alte Methode bleibt! Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 11 Konstruktoren in Subklassen Beim Aufruf des Konstruktors einer abgeleiteten Klasse wird wie folgt vorgegangen: 1. Reservierung des benötigten Speicherplatzes und überschreiben mit 0 2. Aufruf der Konstruktoren von oben nach unten (Top-Down). Beginnend mit der obersten Superklasse bis zur letzten abgeleiteten Klasse. Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 12 Beispiel: Was ist der Output? class SuperKlasse { SuperKlasse(){ System.out.println("SuperKlasse constructor"); }} class SubKlasse extends SuperKlasse { SubKlasse(){ System.out.println("SubKlasse constructor"); }} class SubSubKlasse extends SubKlasse { SubSubKlasse(){ System.out.println("SubSubKlasse constructor"); }} public class KonstruktorDemo { public static void main(String[] args) { SubSubKlasse s = new SubSubKlasse(); }} Ausgabe: SuperKlasse constructor SubKlasse constructor SubSubKlasse constructor 13 Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 Aufruf von Konstruktoren Soll ein Konstruktor der Superklasse mit Parametern aufgerufen werden, muss er explizit (mit super(..)) aufgerufen werden. ACHTUNG! Der Aufruf des Konstruktors der Superklasse ist die erste Anweisung im Konstruktor der Subklasse. class Hund extends Lebewesen{ Hund(String name) { super(name); ... } } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 14 Schlüsselwort super Mit super können generell Methoden von Superklassen aufgerufen werden. Beispiel: class Hund { void bellen(String laut) { System.out.println(laut); } } class Schaeferhund extends Hund { void bellen(String laut) { String newLaut = laut + laut; super.bellen(newLaut); } } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 15 Beispiel: Konstruktoren mit Parameter class SuperKlasse { String f; SuperKlasse(String first) { f = first; System.out.println("SuperKlasse Konstruktor wurde aufgerufen und Instanzvariable f mit " + f + " belegt."); }} class SubKlasse extends SuperKlasse { String s; SubKlasse(String first, String second) { super(first); s = second; System.out.println("SubKlasse Konstruktor wurde aufgerufen und Instanzvariable s mit " + s + " belegt."); }} 16 Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 Beispiel: Konstruktoren mit Parameter (Vortsetzung) class SubSubKlasse extends SubKlasse { String t; SubSubKlasse(String first, String second, String third) { super(first, second); t = third; System.out.println("SubSubKlasse Konstruktor wurde aufgerufen und Instanzvariable t mit " + t + " belegt."); }} public class KonstruktorTest { public static void main(String[] args) { SubSubKlasse s = new SubSubKlasse("First","Second","Third"); }} Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 17 Abstrakte Klassen • Soll es ein einheitliches Interface für alle abgeleiteten Subklassen definiert werden*. • Es wird sichergestellt (Kompiler), dass die Methoden und Parameterlisten des Interfaces in der Subklasse implementiert werden. • In mindestens einer Methode wird nur die Schnittstelle definiert (abstrakte Methode), ihre Implementierung erfolgt in den Subklassen. * ähnlich wie das Java-Konstrukt interface (siehe Foliensatz Interfaces) Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 18 Abstrakte Klassen II • Die Kennzeichnung einer Klasse als abstrakt verhindert, dass Instanzen dieser Klasse erzeugt werden können. • Eine Klasse mit abstrakten Methoden muss als abstrakte Klasse definiert werden. • Alle abstrakten Methoden müssen in den nicht abstrakten Subklassen implementiert werden. • Nicht alle Methoden einer abstrakten Klasse müssen abstrakt definiert sein. Block der • Java-Syntax der Klassendeklaration: Methode fehlt abstract class KlassenName { void aNormalMethod(int a) {...} abstract void aAbstractMethod(int b); } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 19 Abstrakte Superklasse Lebewesen Die Klasse Lebewesen wird als abstract deklariert, die Methode essen muss in allen direkten Subklassen implementiert werden. public abstract class Lebewesen { protected String name; protected int alter; Lebewesen (int age, String name){...}; public void schlafen() {...}; public abstract void essen(); // muss in der Sub-Klasse implementiert werden } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 20 Abstrakte Superklasse 2 Lebewesen public class Loewe extends Lebewesen{ // bekommt name und alter Loewe (int age, String name){ super(age, name); // Konstruktor der Superklasse }; // bekommt schlafen() public void essen() { // muss implementiert werden, da in Super-Klasse abstract System.out.println("Ich laufe " + geschwindigkeit + " km/h"); } } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 21 final + primitive Typ Der Wert der „Variablen“ ist konstant. final int I = 0; I++; /* Anweisung nicht möglich, der Wert von i kann nicht verändert werden.*/ Fehlermeldung des Compilers: Test.java:4: Can't assign a value to a final variable: I I++; ^ 1 error Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 22 final + Objekt-Typ Die Referenz ist konstant. Number.java: class Number { int i; } final Number N1 = new Number(19); Number n2 = new Number(47); N1 = n2; /*Anweisung nicht möglich. Der Variablen N1 kann keine neue Referenz zugewiesen werden.*/ N1.i = n2.i; /* Anweisung möglich! */ Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 23 final + Parameter Parameter ist in der Methode nicht veränderbar. public void deposit(final double VALUE){ VALUE = VALUE * 2; /* Anweisung nicht möglich. Der Variablen VALUE kann kein neuer Wert zugewiesen werden. */ balance+= VALUE; // Anweisung möglich ... } Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 24 final + Methode Das Überschreiben der Methode durch eine Subklasse wird verhindert. class Lebewesen { public final String getName() {...} } • Gründe: Effizienzsteigerung (kein dynamische Binden; siehe Polymophismus) oder Sicherheit. • private + Methode entspricht impliziten final weil die Subklasse keinen Zugriff hat. Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 25 final + Klasse Eine Vererbung dieser Klasse ist nicht möglich. final class FinalClass{} class SubClasse extends FinalClass{} //Anweisung nicht möglich Fehlermeldung des Compilers: Test.java:12: Can't subclass final classes: class Number public class Test extends Number{ • Damit soll die Sicherheit oder Effizienz gesteigert werden. Die Methoden einer final definierten Klasse sind implizit final definiert. 26 Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 Was Sie nach dieser Einheit wissen sollten ... • Java Syntax für Vererbung • Ablauf beim Aufruf von Konstruktoren und das Schlüsselwort super • Zugriffskontrolle mit protected • Zweck von abstract und final Grundzüge der Programmierung – Vererbung © Guth, Hahsler, Kaukal, Klimesch 2000-2002 27