Interfaces und Vererbung Einführung in Java Folie 1 von 31 12. Mai 2011 Ivo Kronenberg
Inhalt Interfaces Statische und dynamische Typen Visiblitätsmodifier Vererbung Überschreiben von Methoden Konstruktoren Abstrakte Basisklassen Mehrfachvererbung Object equals hashcode clone 12. Mai 2011 Folie 2 von 31
Interfaces Anwendung von Interfaces: Trennung zwischen Schnittstelle (Was) und Implementation (Wie). Interface legt den Vertrag zwischen Aufrufer und Implemtation fest (Bindeglied). Für ein Interface kann es verschiedene Implementationen geben (Strategie). Interface ist ein Sprachkonstrukt in Java ähnlich wie die Klasse. 12. Mai 2011 Folie 3 von 31
Interfaces vs. Klassen (Unterschiede) Alle Methoden haben Visibilität public Keine Konstruktoren Nur konstante Datenelemente (static final) Keine Methodenrümpfe (Implementation) 12. Mai 2011 Folie 4 von 31
Interfaces - Syntax Beispiel: // Datei Clock.java Schlüsselwort public interface Clock { public static final int HOURS_PER_DAY = 24; Konstante public int gethour(); Methodenkopf ohne Rumpf 12. Mai 2011 Folie 5 von 31
Interfaces implizite Modifier public interface Clock { public static final int HOURS_PER_DAY = 24; public int gethour(); identisch interface Clock { int HOURS_PER_DAY = 24; int gethour(); 12. Mai 2011 Folie 6 von 31
Interfaces Implementation Schüsselwort public class SimpleClock implements Clock { @Override Annotation public int gethour() { Implementation von Interfacemethode «interface» Clock SimpleClock + gethour() : int 12. Mai 2011 Folie 7 von 31
Interfaces Implementation Implementation muss erfüllen: Interface-Methoden sind implizit public, implementierende Methode muss public sein. Alle Interface Methoden müssen implementiert werden. Signatur von Konstruktor kann nicht durch Interface festgelegt werden. Eine Klasse kann mehrere Interfaces implementieren. 12. Mai 2011 Folie 8 von 31
Interfaces - Typ Eine Interfacedefinition ist ein Typ, gleich wie eine Klasse. Interfacetyp kann in Signaturen verwendet werden (Rückgabewert, Parameter) Zuweisung von Implementation an Interfacetyp Clock clock = new SimpleClock(); Casts Interface zu Implementation: SimpleClock simpleclock = new SimpleClock(); Clock clock = simpleclock; simpleclock = (SimpleClock) clock; Cast nicht nötig Cast nötig 12. Mai 2011 Folie 9 von 31
Statischer und dynamischer Typ Statischer Typ: In Variable deklarierter Typ Prüfung durch Compiler (Einhaltung Vertrag -> Interfaces) Dynamischer Typ: Konkreter Typ von Objektinstanz Methodenaufruf wird nicht durch Compiler festgelegt, sondern zur Laufzeit (dynamisches Binden). Statischer Typ Dynamischer Typ Clock clock = new SimpleClock(); clock.gethour(); Interfacemethode (statischer Typ), Aufruf auf Methode definiert in SimpleClock 12. Mai 2011 Folie 10 von 31
Vererbung Anwendung: Erweiterung Verändern von bestehendem Verhalten Begriffe: Basisklasse: Die Klasse von der abgeleitet wird. Abgeleitete Klasse: Klasse mit Erweiterung. Ableitung: Eine Klasse erbt die Eigenschaften einer Basisklasse Vererbt wird sowohl das Verhalten (Methoden) wie auch die Werte (Datenelemente). 12. Mai 2011 Folie 11 von 31
Vererbung Syntax class Number { int value; int getabsvalue() { return value; Schlüsselwort Basistyp NegativeNumber extends Number { Number - value: int Negativ enumber + getabsvalue() : int 12. Mai 2011 Folie 12 von 31
Visibilitätsmodifier public: Uneingeschränkter Zugriff protected: Zugreifbar von abgeleiteter Klasse (unabhängig von Package) Zugriff aus allen Klassen im gleichen Package Package (default): Zugriff aus allen Klassen im gleichen Package private: Restriktiver Zugriff nur aus eigner Klasse Additiv 12. Mai 2011 Folie 13 von 31
Überschreiben von Methoden Methodensignatur ist identisch (Name, Parameterliste, Rückgabetyp) Visibilitäsmodifier darf gelockert werden, jedoch nicht eingeschränkt (zwingend für statische Typprüfung). Methoden mit Visiblität private können nicht überschrieben werden, sondern nur neu definiert. 12. Mai 2011 Folie 14 von 31
Überschreiben von Methoden Dynamisches Binden public class Basisklasse { public void methode1() { public void methode2() { Überschriebene Methode public class AbgeleiteteKlasse extends Basisklasse { public void methode2() { Basisklasse b = new AbgeleiteteKlasse(); b.methode1(); b.methode2(); 12. Mai 2011 Folie 15 von 31
Überschreiben von Methoden Dynamisches Binden Rein statisch gebunden werden: Konstruktoraufrufe (zu diesem Zeitpunkt existiert noch kein Objekt, dass dynamsich gebunden werden könnte). Statische Methoden (diese gehören zu einer Klasse und nicht zu einer Instanz) Private Methoden (macht keinen Sinn, da diese per Definition nur innerhalb der deklarierenden Klasse verfügbar sind) 12. Mai 2011 Folie 16 von 31
Vererbung Konstruktoren Jeder Konstruktor einer abgeleiteten Klasse muss einen Konstruktor der Basisklasse aufrufen. Wenn nicht definiert, wird default-konstruktor der Basisklasse aufgerufen. Ein Basisklassenkonstruktor kann mit super aufgerufen werden. Der Aufruf des Basiskonstruktors muss erstes Statement innerhalb Konsturktor sein. 12. Mai 2011 Folie 17 von 31
Vererbung Bezug aus Basisklasse public class Basisklasse { public void methode1() { public void methode2() { public class AbgeleiteteKlasse extends Basisklasse { puplic void method1() { public void methode3() { super.method1(); this.method1(); Methode von Basisklasse Methode aus abgeleiteter Klasse 12. Mai 2011 Folie 18 von 31
Abstrakte Basisklasse Eigenschaften von Interfaces aber auch von konkreten Klassen: Interface Abstrakte Klasse Konkrete Klasse Abstrakt Konkret Nicht instanzierbar Kann selbst Methoden ohne Implementation definieren analog zu Interfaces (abstrakte Methoden). Muss ein Interface nicht vollständig Implementieren. 12. Mai 2011 Folie 19 von 31
Abstrakte Basisklasse Beispiel public abstract class Basisklasse { public void doit() { hookmethod(); Aufruf protected void abstract hookmethod(); Abstrakte Methode 12. Mai 2011 Folie 20 von 31
Abstrakte Basisklasse Implementation Alle abstrakten Methoden müssen implementiert werden. Alle noch nicht implementierten Interfacemethoden müssen implementiert werden. Eine implementierende Klasse kann selbst abstrakt sein. Ansonsten gelten die gleichen Regeln wie für konkrete Klassen. Erlaubte Visibilitätsmodifier für abstrakte Methoden: public, protected, package 12. Mai 2011 Folie 21 von 31
Mehrfachvererbung In Java gibt es keine Mehrfachvererbung für Klassen. Eine Klasse kann mehrere Interfaces gleichzeitig implementieren. Ein Interface kann von einem anderen Interface ableiten. 12. Mai 2011 Folie 22 von 31
Dynamische Typinformation Dynamischer Typ kann mit instanceof Operator überprüft werden. Prüfung von Kompatibilität, damit werden auch abgeleitete Klassen einbezogen. Prüfung mit null-referenz möglich. Anwendung für sicheren Typecast if(var instanceof Clock) { Clock varclock = (Clock) var; 12. Mai 2011 Folie 23 von 31
Typobjekt Abfragen von dynamischen Typinformationen in Programm. Typobjekt auf Typ abfragbar über type.class Typobjekt auf Objekt abfragbar über object.getclass() String s = new String(); boolean issametype = (s.getclass() == String.class); Lediglich Typgleichheit wird berücksichtigt, aber nicht Vererbung. 12. Mai 2011 Folie 24 von 31
Object Jede Klasse leitet implizit von Object ab. Vordefinierte überschreibbare Methoden: public String tostring() public boolean equals(object other) public int hashcode() protected Object clone() protected void finalize() Nicht überschreibbare Methoden: public final Class getclass() public final void notifiy() public final void notifyall() public final void wait( ) 12. Mai 2011 Folie 25 von 31
Methode equals Zweck: Vergleichen von zwei Objekten auf inhaltliche Gleichheit. Basisimplementation aus Object vergleicht auf Identität (Referenz). Anforderung an equals: Reflexivität: x.equals(x) == true Symmetrie: x.equals(y) == y.equals(x) Transivität: x.equals(y) und y.equals(z) dann x.equals(z) Konsistenz: Ergebnis ist bei wiederholtem Aufruf gleichbleibend. 12. Mai 2011 Folie 26 von 31
Implementation equals public boolean equals(object other) { if(other == null) return false; if(getclass()!= other.getclass()) return false; if(!super.equals(other)) return false; Clock c = (Clock) other; // Typ Cast von Other // Vergleich aller relevanten Datenelemente instanceof wegen Symmetrie nicht möglich Basisklasse ist nicht Object 12. Mai 2011 Folie 27 von 31
Methode hashcode Zweck: Performante Suche von Objekten in Datenstrukturen. Durch Hashcode erzeugter Hashwert kann beliebig sein. Erzeugung von Hashwert soll schnell gehen. Hashwert soll für unterschiedliche Objekte möglichst nicht gleich sein. Anforderung an hashcode: Hashwert darf sich nicht verändern bei gleich bleibenden Objekt. x.equlas(y) x.hashcode() == y.hashcode() Wenn equals überschrieben wird, muss auch hashcode überschrieben werden. 12. Mai 2011 Folie 28 von 31
Implementation hashcode public int hashcode() { return hour + min + sec; Instanzvariablen 12. Mai 2011 Folie 29 von 31
Klonen von Objekten Erzeugen von unabhängiger Kopie clone muss aktiviert werden durch überschreiben und erweitern der Visibilität. Nebst dem überschreiben von clone muss das Interface Cloneable implementiert werden 12. Mai 2011 Folie 30 von 31
Implementation clone Class Clock implements Cloneable { private int hour; Primitiver Typ private Date date; Referenzdatentyp public Clock clone() throws CloneNotSupportedException { Clock copy = (Clock) super.clone(); Kopiert primitive Datentypen copy.date = (Date) date.clone(); Kopieren von Objekt 12. Mai 2011 Folie 31 von 31