Vererbung Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

Objektorientierte Programmierung
der Universität Oldenburg
der Universität Oldenburg
der Universität Oldenburg
DVG Einfache Klassen Einfache Klassen. DVG Einfache Klassen 2 Strukturen Beispiel: Personendaten bestehen aus –String name –String vorname.
Einführung in die Programmierung Zusammenfassung
Kritische Betrachtung
PKJ 2005/1 Stefan Dissmann Vorwoche - Klasse public class Studierende { private String name, vorname, studiengang; private int matNr, semester; private.
Kapselung , toString , equals , Java API
Progwerkstatt JAVA Klasse, Objekte, Konstruktoren, Methoden
der Universität Oldenburg
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Indirekte Adressierung
Java: Referenzen und Zeichenketten
Java: Grundlagen der Objektorientierung
Vererbung.
Ein Beispiel in Java.
Erweiterte Zuweisungskompatibilität
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Polymorphie (Vielgestaltigkeit)
Interface bzw. Schnittstelle anschaulich: Hüllenklasse
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 5 Polymorphismus Sommersemester 2003 Lars Bernard.
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Diskrete Mathematik I Vorlesung Listen-
Programmieren mit JAVA
Programmieren mit JAVA
Vererbung Spezialisierung von Klassen in JAVA möglich durch
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
PKJ 2005/1 Stefan Dissmann Zusammenfassung Bisher im Kurs erarbeitete Konzepte(1): Umgang mit einfachen Datentypen Umgang mit Feldern Umgang mit Referenzen.
Zusammenfassung Vorwoche
PKJ 2005/1 Stefan Dissmann Klassenhierarchie Person Kunde Goldkunde Lieferant Object.
PKJ 2005/1 Stefan Dissmann Zusammenfassung Vorwoche Methoden sind mit einem Namen versehene Programmabschnitte besitzen Rückgabetyp, Namen, Parameterliste.
Listen Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang
DVG Interfaces. DVG mehrfache Vererbung 4 Mehrfache Vererbung ist die Ableitung einer Klassen von mehreren anderen Klassen. –farbigerPunkt.
Abstrakte Klassen, Interface
DVG Klassen und Objekte
DVG Einfache Klassen 1 Einfache Klassen. 2DVG Einfache KlassenStrukturen Beispiel: Personendaten bestehen aus String name String name.
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Einführung in die Programmierung Wintersemester 2013/14 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
CuP - Java Elfte Vorlesung Montag, 11. November 2002.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2010/11 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Variablenkonzept Klassisch, in Java Basistyp
Parameterübergabemechanismen für den Methodenaufruf
Grundlegende Sortieralgorithmen
CuP - Java Vierte Vorlesung Entspricht ungefähr Kapitel 2.1 des Skriptums Montag, 14. Oktober 2002.
Programmiervorkurs WS 2014/15 Instanzmethoden
CuP - Java Achte Vorlesung Entspricht ungefähr Kapitel 4.1 des Skriptums Montag, 28. Oktober 2002.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
Informatik I : Software höhere Programmiersprachen Java Klassen: hat Methoden (Funktionen) und Daten (Variablen) es kann mehrere Klassen geben nur eine.
Robuste Programme durch Ausnahmebehandlung
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Einführung in die Programmierung mit Java
Einführung in die Programmierung mit Java
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer, Dr. Thomas H. Kolbe Einführung in die Programmierung mit Java 9. Vorlesung WS 2001/2002.
Objektorientierte Programmierung (OOP)
Tutorium Software-Engineering SS14 Florian Manghofer.
Dr. Wolfram Amme, Virtuelle Vererbung, Informatik II, FSU Jena, SS Auflösung von Konflikten bei Mehrfachvererbung Umbenennung mehrdeutiger Methoden.
9. Vererbung und Polymorphie
 Präsentation transkript:

Vererbung Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang http://www.dbs.ifi.lmu.de/Lehre/NFInfoSW

Ziele Den Begriff der einfachen Vererbung verstehen Vererbung und Redefinition von Oberklassenmethoden verstehen Vererbungspolymorphie verstehen Die Klasse Object kennenlernen

Vererbung Klasse D ist Erbe einer Klasse C, falls D alle Attribute und Methoden von C erbt, C D Superklasse von D in UML: Subklasse von C in Java: class D extends C d.h D besitzt alle Methoden und Attribute von C und von allen Oberklassen von C. Man nennt C auch allgemeiner als D bzw. D spezieller als C .

Vererbung Attribute von D = {y}  Attribute von C T2 y C m() T1 x n() Attribute von D = {y}  Attribute von C Methoden von D = {n()}  Methoden von C Folgerung: Die Vererbungsbeziehung ist transitiv: Wenn C von B erbt, dann besitzt D auch alle Attribute und Methoden von B

Vererbung Beispiel: Sparkonto Ein Sparkonto ist ein Bankkonto, bei dem Zinsen gezahlt werden: BankAccount “type var” ist Java-Variante der UML Notation; in Standard UML: “var : type” Analog in Standard UMl: “m(par):resType” statt “resType m(par)” SavingsAccount double interestRate SavingsAccount (double rate) void addInterest () double getInterest()

BankAccount in Java BankAccount - double balance public class BankAccount { private double balance; public BankAccount() { balance = 0.0; } public BankAccount( double initialBalance) { balance = initialBalance; public void deposit(double amount) { balance = balance + amount; public void withdraw(double amount) { balance = balance - amount; public double getBalance() { return balance; public void transferTo(BankAccount other,double amount) { withdraw(amount); other.deposit(amount); BankAccount - double balance + void deposit (double amount) + void withdraw (double amount) + double getBalance() + void transferTo ( BankAccount other, double amount)

Implementierung in Java public class SavingsAccount extends BankAccount { private double interestRate; public SavingsAccount(double rate) { super(0.0); interestRate = rate; } public void addInterest() { double interest = getBalance() * interestRate/100; // auf das Attribut balance kann hier //nicht zugegriffen werden deposit(interest); // geerbte Methode Zugriff auf Konstruktor der Oberklasse siehe später

Vererbung Ist D ist Erbe von C, so gilt: Man kann von D aus nicht direkt auf die privaten Attribute von C zugreifen, sondern nur mittels nichtprivater (geerbter) Zugriffsmethoden von C. Eine Variable der Klasse D kann jede nicht-private Methode von C aufrufen. Einer Variablen der Klasse C kann man ein Objekt eines Nachfahren zuweisen. Beispiel: D d = ...; C c = d; Umgekehrt kann man einer Variablen vom Typ D KEIN Objekt einer Vorfahren- klasse zuweisen. Beispiel: D d1 = c; //falsch!

Abhängigkeitsrelation (Verwendungsrelation, engl. dependency) Die Klasse A ist abhängig von der Klasse C, wenn A Elemente der Klasse C (i.a. Methoden) benützt, UML C A Beispiel: In unserem Beispiel erhalten wir BankAccount SavingsAccount SavingsAccountTest

SavingsAccountTest in Java Beispiel: public class SavingsAccountTest { public static void main(String)[] args) SavingsAccount sparKonto = new SavingsAccount(5); BankAccount konto1 = sparKonto; //ok Sparkonto vom //spezielleren Typ konto1.deposit(1000); // ok // konto1.addInterest(); // nicht ok, da konto1 // nicht den Typ einer // Subklasse hat (SavingsAccount)konto1.addInterest(); // ok, wegen Typcast sparKonto.getBalance(); // ok, geerbte Methode konto1.getBalance(); // ok }

Redefinition von Methoden In vielen Fällen kann man die Implementierung einer Methode m nicht direkt von der Superklasse übernehmen, da z.B. die neuen Attribute in der Superklasse nicht berücksichtigt werden (können). Dann ist es nötig, für die Erbenklasse eine neue Implementierung von m anzugeben. Redefinition von m in UML: Methodenkopf von m wird in der Erbenklasse noch einmal angegeben; Java: neue Implementierung für m im Erben Bemerkung: Bei der Redefinition wird die alte Methode nicht überschrieben; man kann auf sie mit der speziellen Variable „super“ zugreifen. Genauer gesagt, greift man mit super.m() auf die nächste Methodenimplementierung von m in der Vererbungshierarchie zu.

Redefinition von Methoden und Konstruktoren Beispiel: Girokonto Bei einem Girokonto werden bei jeder Transaktion Gebühren verlangt BankAccount deposit withdraw getBalance Redefinition nötig SavingsAccount addInterest getInterest CheckingAccount deductFees deposit withdraw

Redefinition von Methoden Statische Konstanten, die für jede Instanz von CheckingAccount gelten. public class CheckingAccount extends BankAccount { private int transactionCount; public static final int FREE_TRANSACTIONS = 3; public static final double TRANSACTIONS_FEE = 0.3; public void deposit(double d) { super.deposit(d); // Aufruf von BankAccount::deposit transactionCount++; } public void withdraw(double d) { super.withdraw(d); // Aufruf von BankAccount::withdraw transactionCount++; }

Redefinition von Methoden Fortsetzung public void deductFees() { if (transactionCount > FREE_TRANSACTIONS) { double fees = TRANSACTIONS_FEE * (transactionCount - FREE_TRANSACTIONS); super.withdraw(fees); } transactionCount = 0;

Redefinition von Konstruktoren Zugriff auf einen Konstruktor einer Superklasse: super(); // parameterloser Konstruktor bzw. super(p1,...,pn); // Konstruktor mit n Parametern Bemerkung: Dieser Aufruf muss die erste Anweisung des Subklassenkonstruktors sein.

Redefinition von Konstruktoren Beispiel: CheckingAccount public CheckingAccount(double initialBalance) { super(initialBalance); // muss 1. Anweisung sein transactionCount = 0; } Äquivalent dazu könnte man die Methode deposit verwenden: { super.deposit(initialBalance); // super.m() kann // überall im Rumpf // vorkommen // super(); Standardkonstruktor wird automatisch // aufgerufen, wenn 1. Anweisung kein Konstruktor ist.

Falscher Zugriff auf super Man kann mit super(...) nur auf den Konstruktor der direkten Oberklasse zugreifen, aber nicht transitiv auf Konstruktoren weiter oben liegender Klasse. Die Compilerausgabe für diesen, im folgenden Beispiel zu findenden Fehler lautet: >javaC C.java C.java:17: cannot resolve symbol symbol : constructor B (int,int) location: class B super(a, b); ^ 1 error

Redefinition von Methoden und Konstruktoren class A { A(int a, int b) { System.out.println(a); System.out.println(b); } A(){} class B extends A { B(int a, int b, int c) { super(a, b); class C extends B { C(int a, int b, int c, int d) public static void main(String args[]) { C c = new C(1, 2, 3, 4);

Vererbungspolymorphie und dynamisches Binden Man spricht von Vererbungspolymorphie, wenn eine Methode von Objekten von Subklassen aufgerufen werden kann. Dynamisches Binden Falls eine Methode T m(T1 x1,..., Tn xn) mehrere Implementierungen besitzt (die im Vererbungsbaum übereinander liegen), so wird bei einem Aufruf o.m(a1,..., an) die „richtige“ Implementierung dynamisch bestimmt und zwar sucht man ausgehend von der Klasse des dynamischen Typs von o die speziellste Methodendeklaration, auf die der Methodenaufruf anwendbar ist (genauer siehe übernächste Folie). Man nennt dies auch dynamische Bindung, da der Methodenrumpf erst zur Laufzeit ausgewählt wird. Dagegen wird bei statischer Bindung (nicht in Java) der Methodenrumpf zur Übersetzungszeit bestimmt.

Beispiel für Dynamische Bindung D d = exp1; d.n(); F f = exp2; d = f; d.m(); //exp1 sei vom Typ D //Aufruf von n in C //exp2 sei vom Typ F //Wert von d ist Instanz von F //Aufruf von m in E //Aufruf von n in F D m() E m() F n()

Vererbungspolymorphie und dynamisches Binden Methodenaufruf in Java von o.m(a1,...,an)mit o vom Typ D und a1,...,an vom Typ T1,..., Tn . Ein Methodenkopf R m(P1,..., Pn) der Klasse C heißt anwendbar auf o.m(a1,...,an), wenn C gleich D oder allgemeiner als D ist und wenn jedes Pi gleich Ti oder allgemeiner als Ti ist (für i=1,...,n). Für den Aufruf einer Methode wird zunächst zur Übersetzungszeit der speziellste Methodenkopf R m(P1,..., Pn) bestimmt, der auf o.m(a1,...,an) anwendbar ist. Zur Laufzeit suche die speziellste Klasse C mit einer Methodendeklaration mit Namen m und Parametertypen P1,..., Pn, so daß C allgemeiner oder gleich D ist. Wähle diese Methodendeklaration für den Aufruf.

Vererbungspolymorphie und dynamisches Binden Methodenaufruf in Java von o.m(a1,...,an)mit o vom statischen Typ D und a1,...,an vom Typ T1,..., Tn . Ein Methodenkopf R m(P1,..., Pn) der Klasse C heißt anwendbar auf o.m(a1,...,an), wenn C gleich D oder allgemeiner als D ist und wenn jedes Pi gleich Ti oder allgemeiner als Ti ist (für i=1,...,n). Beispiel C C c = exp1; D d = exp2; c.m(); d.n(); d.m(); //m in C anwendbar auf c.m() // aber m in D nicht anwendbar auf c.m() //n in C anwendbar auf d.n() //m in C und D beide anwendbar auf d.m() //m(D x) ist spezieller als m(C x) m() n() m() D m()

Vererbungspolymorphie und dynamisches Binden Methodenaufruf in Java von o.m(a1,...,an)mit o vom statischen Typ D und a1,...,an vom Typ T1,..., Tn . Ein Methodenkopf R m(P1,..., Pn) der Klasse C heißt anwendbar auf o.m(a1,...,an), wenn C gleich D oder allgemeiner als D ist und wenn jedes Pi gleich Ti oder allgemeiner als Ti ist (für i=1,...,n). Beispiel C C c = exp1; D d = exp2; d.m(c); int a = d.n(); d.m(d); //m(C x) in C anwendbar auf d.m(c), aber nicht m(D x) in D // int n() in C anwendbar aber nicht String n() //beide m (in C und D) anwendbar auf d.m(d) m(C x) int n() m() D m(D x) String n()

Vererbungspolymorphie und dynamisches Binden Zur Übersetzungszeit wird zunächst der speziellste Methodenkopf R m(Q1,..., Qn) bestimmt, der auf o.m(a1,...,an) anwendbar ist. Zur Laufzeit bestimme den dynamischen Typ D1 von o; wenn D1 eine Methodendeklaration R m(Q1,..., Qn) enthält, wende diese Methode an; andernfalls suche die speziellste Klasse C mit Methodendeklaration R m(Q1,..., Qn), so daß C allgemeiner oder gleich D1 ist und wähle diese Methodendeklaration für den Aufruf.

Formen der Polymorphie Ad hoc Polymorphie UniversellePolymorphie Überladen . . . . . . Vererbunngs-polymorphie

Formen der Polymorphie Polymorphie: aus dem Griechischen: „vielgestaltig“ Überladen 2 oder mehrere Operationen mit demselben Namen, aber verschiedener Implementierung und Semantik Beispiel: Addition auf ganzen Zahlen und Gleitpunktzahlen Vererbungspolymorphie: Eine Methode der Klasse C kann auch von Objekten eines Subtyps von C aufgerufen werden. Beispiel: deposit von BankAccount kann auch von Instanzen von SavingsAccount aufgerufen werden.

Die Klasse Object Beispiel Object ist die allgemeinste Klasse in Java. Alle Klassen sind Erben von Object. Beispiel Object BankAccount Point Hallo SavingsAccount CheckingAccount

Die Klasse Object Die Klasse Object besitzt u.a. die folgenden Methoden, die man häufig benötigt: Textrepräsentation von this Object String toString() boolean equals(Object o) ... Vergleich zweier Objekte  

Die Klasse Object String toString(): Die toString-Methode erzeugt eine Textrepräsentation einer Klasse. Im Allgemeinen ist es nötig, für selbstdefinierte Klassen eine toString-Methode zu definieren. Beispiel: BankAccount String toString() { return „BankAccount[balance is „ + balance + „]“; }

Die Klasse Object boolean equals(Object o): equals vergleicht die Objektreferenzen von this und o. Im Allgemeinen ist es nötig, für selbstdefinierte Klassen eine equals-Methode zu definieren, wenn die Attributwerte und nicht Objektreferenzen verglichen werden sollen.  o2 o1 this a = null b = 100 :C this.equals(o1) == true this.equals(o2) == false

Zusammenfassung (I) Die Abhängigkeitsbeziehung Die Vererbungsbeziehung gibt an, dass D Symbole der Klasse C verwendet. Die Vererbungsbeziehung hat folgende Eigenschaften: C D C D Für Variablen gilt: Jedes Attribut von C ist automatisch Attribut von D. Möglicherweise kann man aber auch von D nicht direkt darauf zugreifen! Ein neu definiertes Attribut von D ist nicht Attribut von C. Einer lokalen Variablen oder einem Parameter der Klasse C kann ein Objekt der Klasse D zugewiesen werden (aber nicht umgekehrt, dazu ist ein gültiger Cast nötig!)

Zusammenfassung (II) C D Für Methoden gilt: Jede Methode von C ist automatisch eine Methode von D und kann daher mit Objekten von D aufgerufen werden (Vererbungspolymorphie). Eine Methode von D kann aber nicht von einer lokalen Variablen vom Typ C aufgerufen werden. Soll in einem Methodenrumpf auf die Methode der Superklasse zugegriffen werden, verwendet man spezielle Variable super. In der Subklasse D können Methoden redefiniert werden. Solche Methoden müssen im UML-Diagramm der Klasse D explizit genannt werden. Beim Methodenaufruf wird die passende Methodenimplementierung zur Laufzeit ausgewählt (dynamisches Binden) .