Grundzüge der Programmierung Wiederverwendung POLYMORPHIE
Inhalt dieser Einheit Polymorphie: Upcasting Polymorphie Polymophie Theorie 2
Upcasting Def.. 1 Bsp. Shape Upcasting erlaubt die Verwendung eines Objekts einer Subklasse als Objekt seiner Superklasse. Instanzen vom Datentyp Subklasse können dabei einer Variablen vom Datentyp Superklasse zugewiesen werden. z.b. Shape c1 = new Circle(); Oder: Circle c = new Circle(); Shape c1 = c; Shape +randshape() +printcolour(in s : Shape) Circle /*Hier wird die Instanz der Klasse Circle zur Klasse Shape upgecastet.*/ 3
Upcasting 2 Bsp. Shape Objekte der Subklassen können auch dann als Parameter einer Methode übergeben werden, wenn der definierte Datentyp eine Superklasse ist. Methodendeklaration (in der Klasse Shape): public void printcolour(shape s){ } Circle c = new Circle(); c.printcolour(c); Shape +randshape() +printcolour(in s : Shape) Circle 4
Dynamisches Binden 1 z.b.: Shape s = new Circle(); s.draw(); Bsp. Shape /* führt die Methode draw der Klasse Circle aus (=Dynamisches Binden). */ Shape +randshape() +printcolour(in s : Shape) Circle 5
Dynamisches Binden 2 Bsp. Shape z.b.: Circle c = new Circle(); c.printcolour(c); /* führt die Methode printcolour() der Superklasse Shape aus. */ c.draw() ; /* ruft die Methode draw() der Subklasse Circle auf. */ Shape +randshape() +printcolour(in s : Shape) Circle 6
Polymorphie 1 Bsp. Shape Shape +randshape() +printcolour() Circle Triangle Square 7
Polymorphie 2 Bsp. Shape public class UseShapes { public static Shape randshape() { switch((int)(math.random() * 3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } public static void main(string[] args) { Shape[] s = new Shape[9]; // Fill up the array with shapes: for(int i = 0; i < s.length; i++) s[i] = randshape(); // Make polymorphic method calls: for(int i = 0; i < s.length; i++) s[i].draw(); } } sq1 c1 t1 c2 8
Polymorphie 1 Deutsch: Vielgestaltigkeit Kontextabhängige Interpretation von Operatoren, Funktionen und Methoden. Syntaktisch gleiche Nachrichten (an Objekte verschiedener Klassen) rufen semantisch ähnliche Methoden auf. Verschiedene Unterklassen verstehen die gleiche Botschaft und reagieren artgerecht, aber möglicherweise unterschiedlich. Polymorphie erlaubt die schnelle Erweiterung neuer Funktionalitäten durch Implementierung von Subklassen, ohne, dass der restliche Programmcode geändert werden muss. 9
Polymorphie 2 Verwendet dynamic binding, (=late binding oder run-time-binding) Welche Methode aufgerufen wird, kann erst zur Laufzeit (run-time) bestimmt werden, weil erst dann die aktuelle Objektklasse bekannt ist. Polymorphie funktioniert nur im Zusammenhang mit Vererbung und Abstraktion. 10
Polymorphie Wird eine Methode über die Referenz auf eine Superklasse eines Objekts aufgerufen wird dynamisch die Methode des Types des Objekts (der spezifischsten Subklasse) verwendet. Dabei wird eine bottom-up Suche verwendet. 11
Klassenhierarchie Bsp. Account Superklasse Klasse Account int number double balance String name boolean freeze Account double getbalance deposit boolean withdraw boolean check SavingsAccount String password SavingsAccount boolean check boolean checkauthorization CheckingAccount int pin int wrongpincount double maxoverdraft CheckingAccount boolean check boolean checkauthorization boolean repeat String getwrongpinstatus 12
Polymorphie 1 Bsp Account z.b.: SavingsAccount asavingsaccount = new SavingsAccount(); double d = asavingsaccount.getbalance(); /* führt die Methode getbalance der Superklasse Account aus. */ Account Account() getbalance() deposit() withdraw() SavingsAccount SavingsAccount() check() 13
Polymorphie 2 Bsp Account z.b.: CheckingAccount acheckingaccount = new CheckingAccount(); double d = acheckingaccount.withdraw(500); /* führt die Methode withdraw() der Superklasse Account aus, diese ruft die Methode check() der Subklasse CheckingAccount auf. */ siehe Account.java Account Account() deposit() withdraw() check() CheckingAccount CheckingAccount() check() 14
Upcasting Def.. 1 Bsp Account Upcasting erlaubt die Verwendung eines Account Objekts einer Subklasse als Objekt seiner Superklasse. Instanzen vom Datentyp Subklasse SavingsAccount können dabei einer Variable vom Datentyp Superklasse zugewiesen werden. z.b. Account a = new CheckingAccount(); oder CheckingAccount ca1 = new CheckingAccount(); Account a = ca1; /* Hier wird die Instanz der Klasse CheckingAccount zur Klasse Account upgecastet.*/ 15
Upcasting Def.. 2 Bsp Account Objekte der Subklassen können auch dann als Parameter einer Methode übergeben werden, wenn der definierte Datentyp eine Superklasse ist. Methodendeklaration: class Kundenbetreuer { public void anlageberatung(account a){ Account SavingsAccount if (a.getbalance() > 100000) } } siehe Bankfiliale.java 16
Upcasting Def.. 3 Bsp Account Objekte der Subklassen als Parameter übergeben. Methodenaufruf: Kundenbetreuer k1 = new Kundenbetreuer(); CheckingAccount ca1 = new CheckingAccount(); k1.anlageberatung(ca1); Account a = new SavingsAccount(); k1.anlageberatung(a); 17
Upcasting Def.. 4 Bsp Account Objekte der Subklassen können auch in Datenstrukturen gespeichert werden, die für Instanzen der Superklasse definiert sind. Account[] kunden = new Account[3]; kunden[0] = new SavingsAccount(); kunden[1] = new CheckingAccount(); k1.anlageberatung(kunden[0]); k1.anlageberatung(kunden[1]); z.b.: Bankfiliale.java 18
Upcasting & Polymorphie Bsp Account z.b.: Account a = new CheckingAccount(); bool b = a.check(); /* führt die Methode check der Klasse CheckingAccount aus. */ Account Account() getbalance() deposit() check() CheckingAccount CheckingAccount() check() 19
Upcasting 1 Bsp Animal z.b. Hierarchie Animal/Mammal/Cat alle haben eat() codiert. Cat simon = new Cat(); Animal creature = simon; //upcasting creature.eat(); //polymorph, dh. es //wird Cat.eat() aufgerufen Animal eat() Mammal eat() Cat eat() 20
Upcasting 2 Bsp Animal z.b. Methode feed() einer anderen Klasse. void feed(animal a ){ a.eat(); // Dyn. Binding } Dog rover = new Dog(); Cat simon = new Cat(); feed(rover); //Dog.eat() feed(simon); //Cat.eat() Cat eat() Animal eat() Mammal eat() Dog eat() 21
Fehlerquelle ACHTUNG: Das Überschreiben einer Methode mit anderen Parametern führt zu Overloading (kein Polymorphismus)! class Cat { void eat(catfood food){} Animal eat() Mammal eat() feed(simon); Cat /* führt wegen der Signature nicht zum eat(catfood f) Aufruf von Cat.eat(..)*/ vgl. auch c07:winderror.java [Ecke00] 22
Lernkontrolle Analysieren Sie das Beispiel c07:sandwich.java aus [Ecke00] Bestimmen Sie den Bildschirmoutput. Vergleichen Sie Ihr Ergebnis mit dem tatsächlichen Ergebnis. 23