Algorithmik 1 M. Philippsen, H. Stoyan, M. Stamminger Friedrich-Alexander-Universität Erlangen-Nürnberg Informatik 2/8/9 Kapitel 5 - Objektorientierung 5.1 5.2 5.3 5.4 5.5 Sichtbarkeit in Java Modularität Klassenhierarchien Polymorphie und Typsicherheit Beispiel Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-2 M. Stamminger 5.1 Sichtbarkeit in Java Gültigkeitsbereich eines Namens („scope“) class class Uhr Uhr {{ long long minuten; minuten; long long stunden; stunden; void void setzeZeit(long setzeZeit(long stunden, stunden, long long minuten) minuten) {{ this.minuten this.minuten == minuten; minuten; this.stunden this.stunden == stunden; stunden; }} Uhr Uhr kopiere() kopiere() {{ Uhr Uhr cc == new new Uhr(); Uhr(); c.stunden c.stunden == stunden; stunden; c.minuten c.minuten == minuten; minuten; c.zeitzone c.zeitzone == zeitzone; zeitzone; return return c; c; }} ... ... }} minuten, stunden sichtbar außerhalb und innerhalb von Uhr Parameter sichtbar in setzeZeit Attribute der Klasse Uhr überdeckt in setzeZeit, sichtbar über Referenz this (=Verweis auf das Objekt selbst) c sichtbar in kopiere Attribute von c sichtbar in kopiere this nicht nötig, da Attribute der Klasse Uhr nicht überdeckt Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-3 M. Stamminger 5.1 Sichtbarkeit in Java Kapselungsprinzip („encapsulation“) Dem Benutzer einer Klasse sollten die Interna der Klasse nicht zugänglich sein: y Geheimnisprinzip: Kenntnisse über Attribute und Methodenimplementierungen gelangen nicht nach außen. y Unabhängigkeit: Programmierung möglich ohne Rücksicht auf andere; Änderung einer Implementierung hat keine Effekte auf andere. Für die Benutzer dürfen nur Schnittstellen nach außen sichtbar sein; das sind folglich die Methodensignaturen (Benutzersicht). Aber: Die Klassenvereinbarungen belassen volle Einsicht in die Implementierung. Diese dürfen daher nur einem Ersteller der Klasse bekannt sein (Anbietersicht). Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-4 M. Stamminger 5.1 Sichtbarkeit in Java Klasse („class“) Schnittstelle („interface“) Dienst Dienst Algorithmen und Datenstrukturen implements Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-5 M. Stamminger 5.1 Sichtbarkeit in Java Schnittstelle („interface“) Eine Schnittstelle ist an keine Methodenimplementierungen gebunden; sie beschreibt nur deren Signaturen. Eine Implementierung der angegebenen Methoden muss also in einer Klasse erfolgen. Eine Klasse kann keine, eine oder mehrere Schnittstellen implementieren. Bei Objektvariablen kann als Typ statt einer Klasse eine Schnittstelle angegeben werden. y Die Referenz kann aber nur auf ein Objekt verweisen. y Wird ihr ein Objekt zugewiesen, so muss dessen Klasse die Schnittstelle implementieren. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-6 M. Stamminger 5.1 Sichtbarkeit in Java Schnittstellen werden in Java durch das Schlüsselwort interface eingeleitet. Durch implements wird angegeben, dass eine Klasse mindestens die in der Schnittstelle angegebenen Methoden implementiert. Schnittstelle interface interface Taktgeber Taktgeber {{ long long leseZeitInSekunden(); leseZeitInSekunden(); }} class class Uhr Uhr implements implements Taktgeber Taktgeber {{ ... ... long long leseZeitInSekunden() leseZeitInSekunden() {{ return return (stunden*3600)+(minuten*60); (stunden*3600)+(minuten*60); }} ... ... }} Taktgeber Taktgeber tt == new new Uhr(); Uhr(); long long ll == t.leseZeitInSekunden(); t.leseZeitInSekunden(); Klasse muss Methoden der Schnittstelle enthalten! Variable vom Typ der Schnittstelle garantiert, dass Methoden-Code vorhanden ist. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-7 M. Stamminger 5.1 Sichtbarkeit in Java Zugriffsbeschränkungen („visibility“) Abschwächung: Der Zugriff auf Klassen, Attribute und Methoden von außen kann durch den Klassenimplementierer mittels Modifikatoren („modifier“) eingeschränkt werden. private gibt an, dass nur von innerhalb der Klasse selbst auf das Attribut bzw. die Methode zugegriffen werden kann. public gibt an, dass ein Zugriff von überall auf das Attribut bzw. die Methode möglich ist. ... und ohne Modifikator? s.u. public public class class Uhr Uhr {{ // // Zugriff Zugriff auf auf Attribute Attribute von von außen außen nicht nicht möglich möglich private private long long minuten; minuten; private private long long stunden; stunden; // // Zugriff Zugriff von von außen außen nur nur über über Methoden Methoden möglich möglich public Uhr() { ... } public Uhr() { ... } public public void void setzeZeit(long setzeZeit(long std, std, long long min) min) {{ ... ... }} ... ... }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-8 M. Stamminger 5.2 Modularität Modul Ein Modul ist eine Komponente mit einer gewissen Abgeschlossenheit: Es erbringt Dienste, nimmt aber kaum welche in Anspruch. Ein Modul ist somit ein Teilsystem mit einer klaren und schmalen Grenze zu seiner Umgebung. Modularisierung Eine Modularisierung eines Systems erfolgt zum Zwecke der Übersichtlichkeit, Arbeitsteilung, Wiederverwendung, ... Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-9 M. Stamminger 5.2 Modularität Paket („package“) Zusammenstellung der Vereinbarungen von als zusammengehörig betrachteten Java-Klassen und Java-Interfaces. Ein Paket besitzt einen Namen, der - wie von Dateiverzeichnissen her bekannt - hierarchisch aufgebaut sein kann: y y y y java.lang uhren com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese Der Paketname definiert einen Namensraum für die im Paket vorkommenden Klassendeklarationen. y Es wäre daher durchaus möglich innerhalb des Pakets uhren eine Klasse String zu realisieren. Durch Verwendung qualifizierter Klassennamen (java.lang.String bzw. uhren.String) kann Eindeutigkeit erreicht werden. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-10 M. Stamminger 5.2 Modularität Bei der Klassendeklaration kann das Paket, in das die Klasse kommen soll, mit package angegeben werden Zugriff auf eine Klasse in einem Paket über qualifizierten Namen = <Paketname>.<Klassename>. Alternative: Paketname wird mittels import bekannt gemacht. Dann reicht <Klassenname>. Schnittstelle ist im package package uhren; uhren; selben Paket. Daher interface interface Taktgeber Taktgeber {{ ist Name bekannt. long long leseZeitInSekunden(); leseZeitInSekunden(); }} package package uhren; uhren; public public class class Uhr Uhr implements implements Taktgeber Taktgeber {{ ... ... }} uhren.Taktgeber uhren.Taktgeber tt == new new uhren.Uhr(); uhren.Uhr(); import import uhren.*; uhren.*; Taktgeber Taktgeber tt == new new Uhr(); Uhr(); Zur Verwendung ohne import: qualifizierten Name verwenden. Import macht Namen aus Paket bekannt; Kurzform dann nutzbar. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-11 M. Stamminger 5.2 Modularität Klassenbibliothek („library“) Sammlung vordefinierter, häufig verwendeter Klassen, auf die bei der Programmierung zugegriffen werden kann. In Java ist dies eine Menge von Paketen. Java selbst liefert zum Beispiel die Pakete: y y y y y y y java.awt Klassen für GUIs (Abstract Window Toolkit) java.io Ein-/Ausgabe in Dateien o.ä. java.lang Zentrale Klasse von Java (z.B. Object) java.net Verwaltung von Netzwerkverbindungen java.sql Datenbankanbindung java.util Nützliche Klassen (z.B. Kalender, Listen) javax.swing Graphische Oberfläche Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-12 M. Stamminger 5.2 Modularität Zugriffsbeschränkungen (1) global Unterklassen Paket protected Klasse public (ohne) Unterklassen Klassen-/Schnittstellenname Der Name von Klassen/Schnittstellen, y … die ohne Modifikator deklariert sind, ist nur im selben Paket sichtbar. y … die als public deklariert sind, ist global sichtbar (und kann z.B. importiert werden). y … die als protected deklariert sind, ist nur in deren Unterklassen und Unterschnittstellen sichtbar (unabhängig davon, in welchem Paket diese liegen). Als final deklarierte Klassen dürfen keine Unterklassen haben. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-13 M. Stamminger 5.2 Modularität Zugriffsbeschränkungen (2) Sofern die enthaltende Klasse erreichbar ist: global Unterklassen Unterklassen Gemäß Zugreifbarkeit d. enthaltenden Klasse Paket Methode Attribut Friedrich-Alexander-Universität Erlangen-Nürnberg public protected private (ohne) Klassenname Algorithmik 1, WS 2005/06, Folie 0-14 Unterklassen protected Klasse public (ohne) Unterklassen Attribut-/Methodenname final : nicht überschreibbar M. Stamminger 5.2 Modularität Zugriffsbeschränkungen für Methoden/Attribute (textuell) Sofern die enthaltende Klasse erreichbar ist, gilt: public von überall zugreifbar, am wenigsten restriktiv private niemand außerhalb der (enthaltenden) Klasse kann zugreifen protected Zugriff aus allen Klassen des selben Pakets möglich (wenn die enthaltende Klasse da auch sichtbar ist.) Zugriff in allen Unterklassen möglich (auch wenn diese in anderen Paketen liegen). (ohne)von überall im Paket zugreifbar Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-15 M. Stamminger 5.2 Modularität classpath Übersetzt man eine Klasse Bsp aus dem Paket Foo.Bar, dann wird der erzeugte Code (Bsp.class) im Verzeichnis <dir>/Foo/Bar bzw. <dir>\Foo\Bar abgelegt. y Mit der Option -d kann man <dir> beim Übersetzen angeben, falls nicht das aktuelle Verzeichnis gemeint ist. y Beispiel: javac –d ~/classes Bsp.java //Unix Will man die main-Routine dieser Klasse starten, so muss man den voll qualifizierten Klassennamen angeben: java Foo.Bar.Bsp Also nicht den Dateinamen angeben! Damit der Übersetzer und das Java-Laufzeitsystem den erzeugten Code findet, muss <dir> in der Umgebungsvariable CLASSPATH eingetragen sein. y Beispiel: setenv CLASSPATH ~/classes //Unix Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-16 M. Stamminger 5.3 Klassenhierarchien Vererbung zwischen Schnittstellen Zwischen zwei Schnittstellen wird in Java sowohl Einfach- als auch Mehrfachvererbung unterstützt, wobei extends die Schnittstelle(n) angibt, deren Signaturen übernommen werden: interface interface TaktgeberMillisekunden TaktgeberMillisekunden extends extends Taktgeber Taktgeber {{ ... ... }} Werden zwei gleich benannte Methoden über verschiedene Pfade ererbt, y so wird bei identischen Signaturen eben diese Signatur übernommen und y so werden bei unterschiedlichen Signaturen beide übernommen und dann als überladene Methoden behandelt. Mehr in Abschnitt 7.2 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-17 M. Stamminger 5.3 Klassenhierarchien Überschreiben von Methoden („method overriding“) Eine Unterklasse kann eine neue Implementierung für eine ererbte (Objekt/Instanz-)Methode bereit halten. (Nicht für Klassenmethoden) Dann kann immer noch auf die Implementierung der direkten Oberklasse über die Referenz super zugegriffen werden. class class Uhr Uhr {{ ... ... public public void void anzeigen() anzeigen() {} {} }} class class AnalogUhr AnalogUhr extends extends Uhr Uhr {{ ... ... // // Selbe Selbe Signatur Signatur wie wie in in Oberklasse Oberklasse public public void void anzeigen() anzeigen() {{ super.anzeigen(); super.anzeigen(); // // führt führt Code Code von von Uhr.anzeigen()aus Uhr.anzeigen()aus ... ... }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-18 M. Stamminger 5.3 Klassenhierarchien Überschreiben versus Überladen Überladene Methoden Überschriebene Methoden haben unterschiedliche Signaturen haben dieselben Signaturen y Klassenmethoden können keine Instanzmethoden überschreiben y Umgekehrt auch nicht haben i.A. unterschiedliche Implementierungen Vorkommen: y In einer Klasse und einer ihrer Unterklassen y in einer Klasse und einer ihrer Unterklassen oder y in einer Klasse (nebeneinander) Statische Methoden können überladen werden haben i.A. unterschiedliche Implementierungen Vorkommen: Statische Methoden können nicht überschrieben werden (wohl aber verdeckt Æ nächster Abschnitt.) Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-19 M. Stamminger 5.3 Klassenhierarchien Abstrakte Klasse in Java („abstract class“) Zur Erinnerung: y Oberklasse mit nur partieller Implementierung; restliche Implementierung muss in einer Unterklasse nachgeholt werden. y Mischung aus Klasse und Schnittstelle, daher keine Ausprägungen mögl. abstract abstract class class Uhr Uhr {{ ... ... abstract abstract void void anzeigen(); anzeigen(); }} class class AnalogUhr AnalogUhr extends extends Uhr Uhr {{ ... ... void void anzeigen() anzeigen() {{ ... ... }} }} Abstrakte Methode: legt nur Aufrufschnittstelle ohne Implementierung fest. Unterklasse liefert die Implementierung, die zur Schnittstelle passt. Hat eine Klasse eine Schnittstelle als Obertyp und implementiert sie aber nicht alle Methoden der Schnittstelle, so ist sie ebenfalls abstrakt. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-20 M. Stamminger 5.3 Klassenhierarchien Wurzel der Hierarchie Eine Klasse, die nicht explizit Unterklasse einer anderen Klasse ist, ist stets implizit Unterklasse von java.lang.Object. Die Klasse Object hat eine Reihe von Methoden, die vor allem bei der Arbeit mit parallelen Kontrollfäden relevant werden Æ später mehr. Wichtige Methode: String toString() y Liefert textuelle Repräsentation des Objekts. y System.out.println(Object) ruft toString() auf. y Die Standardimplementierung sollte daher bei eigenen Objekten überschrieben werden, wenn man ihren Zustand einfach ausdrucken möchte. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-21 M. Stamminger 5.4 Polymorphie und Typsicherheit Polymorphie („polymorphism“) = Fähigkeit, verschiedene Gestalt anzunehmen Eine polymorphe Operation („polymorphic operation“) kann auf Objekte verschiedener Klassen ausgeführt werden und jeweils ein anderes Verhalten haben y Entstehung polymorpher Operationen durch Überladen à Beispiel: println(long), println(float), println(Object) Je nachdem von welchem Typ das Argument o im Aufruf println(o) ist, wird die „passende Version“ der Methode println aufgerufen. y Entstehung polymorpher Operationen durch Überschreibung à Beispiel: java.lang.Object hält eine Standardimplementierung von toString() bereit, die (bei Bedarf) in eigenen Klassen überschrieben wird. Je nach dem Typ eines Objekts o wird bei o.toString() unterschiedlicher Code ausgeführt. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-22 M. Stamminger 5.4 Polymorphie und Typsicherheit Eine polymorphe Variable („polymorphic variable“) kann im Laufe der Ausführung eines Programms Referenzen auf Objekte von verschiedenen Klassen haben. Eine polymorphe Variable hat einen y statischen Typ: Dieser wird durch Angabe der Klasse bei der Deklaration angegeben und kann bei der Übersetzung überprüft werden y dynamischen Typ: Dieser wird durch die Klasse des Objekts angegeben, auf den Variable zur Laufzeit zeigt. Object Object c; c; //statischer //statischer Typ Typ von von c: c: Object Object cc == new new Uhr(); Uhr(); //dynamischer //dynamischer Typ Typ von von c: c: Uhr Uhr c.anzeigen(); c.anzeigen(); //Nicht //Nicht typsichere typsichere Sprachen Sprachen führen führen zur zur //Laufzeit //Laufzeit die die Methode Methode anzeigen anzeigen der der Klasse Klasse //Uhr (dynamischer Typ von o) aus. //Uhr (dynamischer Typ von o) aus. Java ist typsicher. Der statische Typ von c (Klasse Object) deklariert keine Methode anzeigen. Daher Fehlermeldung des Übersetzers. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-23 M. Stamminger 5.4 Polymorphie und Typsicherheit Polymorphe Variablen in typsicheren Sprachen Sei v eine Variable mit Referenzsemantik vom Typ T/der Klasse T. Dann dürfen der Variablen v Verweise auf Objekte der Klasse T oder einer beliebigen Unterklasse von T zugewiesen werden. y Die Unterklasse verfügt über alle Eigenschaften der Oberklasse und kann daher deren Platz einnehmen. Uhr //statischer Uhr cc == new new Uhr(); Uhr(); //statischer Typ Typ von von c: c: Uhr Uhr cc == new AnalogUhr(); //dynamischer Typ von c: new AnalogUhr(); //dynamischer Typ von c: AnalogUhr AnalogUhr // // Typsicherheit: Typsicherheit: // // Alle Alle Methoden Methoden von von Uhr Uhr können können auf auf cc aufgerufen aufgerufen werden werden c.anzeigen() //die c.anzeigen() //die anzuwendende anzuwendende Implementierung Implementierung //wird //wird zur zur Laufzeit Laufzeit ausgewählt ausgewählt y Typsicherheit: Es dürfen nur Methoden aufgerufen werden, die schon beim statischen Typ von c (Oberklasse Uhr) verfügbar sind. Diese Methoden sind durch Vererbung in jedem Fall bei allen Objekten beliebiger Unterklassen verfügbar (ggf. überschrieben.) Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-24 M. Stamminger 5.4 Polymorphie und Typsicherheit Dynamisches Binden („late binding“) Die auszuführende Implementierung einer Instanzmethode wird erst zur Laufzeit festgelegt. (Zeitbedarf!) Oft auch als virtueller Methodenaufruf bezeichnet. Hierzu muss dynamischer Typ des aktuellen Objektes bekannt sein. Nach einer Implementierung wird zur Laufzeit zuerst bei dieser Klasse und dann aufsteigend in den Oberklassen gesucht. y Bei Mehrfachvererbung nicht eindeutig, daher in Java nicht zugelassen. Uhr Uhr cc == new new Uhr(); Uhr(); c.setzeZeit(11, c.setzeZeit(11, 42); 42); c.anzeigen(); c.anzeigen(); // // Implementierung Implementierung in in Uhr Uhr // // Implementierung Implementierung in in Uhr Uhr cc == new new AnalogUhr(); AnalogUhr(); c.setzeZeit(11, c.setzeZeit(11, 42); 42); c.anzeigen(); c.anzeigen(); // // Implementierung Implementierung in in Uhr Uhr // // Implementierung Implementierung in in AnalogUhr AnalogUhr Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-25 M. Stamminger 5.4 Polymorphie und Typsicherheit Statisches Binden Während Instanzmethoden in Java dynamisch gebunden werden, werden Klassenmethoden (static) statisch gebunden. class class Super Super {{ static static String String greeting() greeting() {{ return return "Goodnight"; "Goodnight"; }} String String name() name() {{ return return "Richard"; "Richard"; }} }} class class Sub Sub extends extends Super Super {{ static static String String greeting() greeting() {{ return return "Hello"; "Hello"; }} String String name() name() {{ return return "Dick"; "Dick"; }} Statischer Typ: Super }} class class Test Test {{ Dynamischer Typ: Sub public static void main(String[] args) { public static void main(String[] args) { Super Super ss == new new Sub(); Sub(); System.out.println(s.greeting() System.out.println(s.greeting() ++ ", ", "" ++ s.name()); s.name()); }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-26 Liefert: „Goodnight, Dick“ M. Stamminger 5.4 Polymorphie und Typsicherheit Klasse versus Typ Typ y Eigenschaft von Variablen und Ausdrücken y definiert Mindestforderung bzgl. anwendbarer Operationen y rein syntaktisch festgelegt (statisch ermittelbar) Klasse y y y y stellt Konstruktor(en) für Objekte bereit (- gilt nicht für abstrakte Klassen!) definiert Signatur oder Implementation der Operationen Ein Objekt gehört zu der Klasse mit deren Konstruktor es konstruiert wurde. Mit der Klassendefinition wird ein gleichnamiger Typ eingeführt Beachte: y Variablen gleichen Typs können Objekte unterschiedlicher Klassenzugehörigkeit referieren (benennen). y Die werden sich i.a. unterschiedlich verhalten. y Beispiel: Oberklasse A mit zwei Unterklassen A1 und A2.Variable kann mit Typ A deklariert werden und kann Objekte aus A1 und A2 referieren. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-27 M. Stamminger 5.4 Polymorphie und Typsicherheit Typumwandlung („casting“) Zu welcher Klasse ein konkretes Objekt gehört, lässt sich mit instanceof überprüfen. Uhr Uhr c; c; ... ... if if (c (c instanceof instanceof DigitalUhr) DigitalUhr) {{ ... ... }} Im Inneren der if-Anweisung hat c immer noch den statischen Typ Uhr. Methoden, die nur die Unterklasse DigitalUhr anbietet, können wegen der geforderten Typsicherheit nicht aufgerufen werden. Abhilfe: explizite Typwandlung In Java wird zur Laufzeit Uhr sichergestellt, dass diese Uhr c; c; ... ... Typwandlung korrekt ist. if if (c (c instanceof instanceof DigitalUhr) DigitalUhr) {{ DigitalUhr DigitalUhr digital digital == (DigitalUhr)c; (DigitalUhr)c; ... ... }} digital hat anderen statischen Typ als c. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-28 M. Stamminger 5.4 Polymorphie und Typsicherheit Typumwandlung am Beispiel public public class class UhrenKonfiguration UhrenKonfiguration {{ public public static static Uhr Uhr konfigurieren(Uhr konfigurieren(Uhr c) c) {{ if if (c (c instanceof instanceof AnalogUhr) AnalogUhr) {{ AnalogUhr AnalogUhr analog analog == (AnalogUhr)c; (AnalogUhr)c; analog.setzeZifferblattfarbe(java.awt.Color.blue); analog.setzeZifferblattfarbe(java.awt.Color.blue); return return analog; analog; }} else else if if (c (c instanceof instanceof DigitalUhr) DigitalUhr) {{ DigitalUhr DigitalUhr digital digital == (DigitalUhr)c; (DigitalUhr)c; digital.setzeSchriftgroesse(30); digital.setzeSchriftgroesse(30); return return digital; digital; }} else else {{ return return c; c; DigitalUhr-spezifische }} Methoden werden aufgerufen. }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-29 M. Stamminger 5.4 Polymorphie und Typsicherheit Überschreiben versus Verdecken Auf verdeckte Variablen und verdeckte (statische) Methoden (der Oberklasse) kann recht einfach zugegriffen werden y Im Inneren der verdeckenden Klasse: super… y Von Außen: Vorher Typwandlung auf gewünschte Klasse Eine überschriebene Instanzmethode der Oberklasse y kann nur im Inneren der überschreibenden Klasse per super… aufgerufen werden. y Ein Aufruf von außen ist nicht möglich. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-30 M. Stamminger 5.4 Polymorphie und Typsicherheit Überschreiben versus Verdecken am Beispiel class class Super Super {{ String String hi hi == „Hi"; „Hi"; String String name() name() {{ return return "Richard"; "Richard"; }} }} class class Sub Sub extends extends Super Super {{ String String hi hi == „Hello"; „Hello"; String name() String name() {{ return return "Dick"; "Dick"; }} }} Super Super ss == new new Sub(); Sub(); s.hi //Hi s.hi //Hi ((Sub)s).hi //Hello ((Sub)s).hi //Hello ((Super)s).hi //Hi ((Super)s).hi //Hi s.name(); //Dick s.name(); //Dick ((Sub)s).name() ((Sub)s).name() //Dick //Dick ((Super)s).name() ((Super)s).name() //Dick //Dick Auch beim Zugriff auf Instanzvariablen wird statisch gebunden. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-31 M. Stamminger 5.5 Beispiel Implementierung der Klasse Uhr (1) package package uhren; uhren; import import java.util.Date; java.util.Date; import uhren.Taktgeber; import uhren.Taktgeber; import import uhren.TimeZone; uhren.TimeZone; public public abstract abstract class class Uhr Uhr implements implements Taktgeber Taktgeber {{ private private static static long long zaehler zaehler == 0; 0; private long seriennummer; private long seriennummer; private minuten; private long long minuten; private stunden; private long long stunden; private zeitzone private TimeZone TimeZone zeitzone == new new TimeZone("UTC"); TimeZone("UTC"); private private final final Date Date herstellungsdatum herstellungsdatum == new new Date(); Date(); public public Uhr() Uhr() {{ seriennummer seriennummer == zaehler; zaehler; zaehler++; zaehler++; }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-32 M. Stamminger 5.5 Beispiel Implementierung der Klasse Uhr (2) ... ... public public Uhr(long Uhr(long min) min) {{ this(); this(); stunden stunden == min min // 60; 60; minuten minuten == min min %% 60; 60; }} public public abstract abstract void void anzeigen(); anzeigen(); public public void void setzeZeit(long setzeZeit(long std, std, long long min) min) {{ stunden stunden == std; std; minuten minuten == min; min; }} public public void void setzeZeit(long setzeZeit(long std) std) {{ setzeZeit(std, setzeZeit(std, 0); 0); }} public public long long leseZeitInSekunden() leseZeitInSekunden() {{ return return (stunden (stunden ** 3600) 3600) ++ (minuten (minuten ** 60); 60); }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-33 M. Stamminger 5.5 Beispiel Implementierung der Klasse Uhr (3) ... ... public public void void setzeZeitZone(TimeZone setzeZeitZone(TimeZone tz) tz) {{ if if (tz (tz == == null) null) {{ return; return; }} zeitzone zeitzone == tz; tz; }} public public TimeZone TimeZone leseZeitZone() leseZeitZone() {{ return return zeitzone; zeitzone; }} ... ... }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-34 M. Stamminger 5.5 Beispiel Abgeleitete Klasse AnalogUhr package package uhren; uhren; import import java.awt.Color; java.awt.Color; import uhren.Uhr; import uhren.Uhr; public public class class AnalogUhr AnalogUhr extends extends Uhr Uhr {{ private private Color Color zifferblattfarbe; zifferblattfarbe; public public AnalogUhr(long AnalogUhr(long min) min) {{ super(min); super(min); }} public public void void anzeigen() anzeigen() {{ ... ... }} public public void void setzeZifferblattfarbe(Color setzeZifferblattfarbe(Color c) c) {{ zifferblattfarbe zifferblattfarbe == (c (c == == null) null) ?? Color.blue Color.blue :: c; c; }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-35 M. Stamminger 5.5 Beispiel Abgeleitete Klasse DigitalUhr package package uhren; uhren; import import uhren.Uhr; uhren.Uhr; public public class class DigitalUhr DigitalUhr extends extends Uhr Uhr {{ private private int int schriftgroesse; schriftgroesse; public public DigitalUhr(long DigitalUhr(long min) min) {{ super(min); super(min); }} public public void void anzeigen() anzeigen() {{ ... ... }} public public void void setzeSchriftgroesse(int setzeSchriftgroesse(int groesse) groesse) {{ schriftgroesse schriftgroesse == (groesse (groesse <= <= 0) 0) ?? 10 10 :: groesse; groesse; }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-36 M. Stamminger 5.5 Beispiel Schnittstelle Taktgeber und Klasse TimeZone package package uhren; uhren; interface interface Taktgeber Taktgeber {{ long long leseZeitInSekunden(); leseZeitInSekunden(); }} package package uhren; uhren; public public class class TimeZone TimeZone {{ private private String String identifikator; identifikator; public public TimeZone(String TimeZone(String id) id) {{ setzeIdentifikator(id); setzeIdentifikator(id); }} public public void void setzeIdentifikator(String setzeIdentifikator(String id) id) {{ identifikator identifikator == id; id; }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-37 M. Stamminger 5.5 Beispiel Klasse zur Konfiguration einer Uhr package package uhren; uhren; import import uhren.*; uhren.*; import import java.awt.Color; java.awt.Color; public public class class UhrenKonfiguration UhrenKonfiguration {{ public public static static Uhr Uhr konfigurieren(Uhr konfigurieren(Uhr c) c) {{ if if (c (c instanceof instanceof AnalogUhr) AnalogUhr) {{ AnalogUhr AnalogUhr analog analog == (AnalogUhr)c; (AnalogUhr)c; analog.setzeZifferblattfarbe(Color.blue); analog.setzeZifferblattfarbe(Color.blue); return return analog; analog; }} else if (c else if (c instanceof instanceof DigitalUhr) DigitalUhr) {{ DigitalUhr DigitalUhr digital digital == (DigitalUhr)c; (DigitalUhr)c; digital.setzeSchriftgroesse(30); digital.setzeSchriftgroesse(30); return return digital; digital; }} else else {{ return return c; c; }} }} }} Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2005/06, Folie 0-38 M. Stamminger