Kapitel 5 - Objektorientierung 5.1 5.2 5.3 5.4 5.5 Algorithmik 1 Sichtbarkeit in Java Modularität Klassenhierarchien Polymorphie und Typsicherheit Beispiel Prof. Dr. Michael Philippsen Friedrich-Alexander-Universität Erlangen-Nürnberg Informatik 2 • Programmiersysteme Martensstraße 3 • 91058 Erlangen Handy aus! Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-2 5.1 Sichtbarkeit in Java M. Philippsen 5.1 Sichtbarkeit in Java Gültigkeitsbereich eines Namens („scope“) class Uhr { long minuten; long stunden; Kapselungsprinzip („encapsulation“) minuten, stunden sichtbar außerhalb und innerhalb von Uhr void setzeZeit(long stunden, long minuten) { this.minuten = minuten; this.stunden = stunden; } Uhr kopiere() { Uhr c = new Uhr(); c.stunden = stunden; c.minuten = minuten; c.zeitzone = zeitzone; return c; } ... } 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 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). this nicht nötig, da Attribute der Klasse Uhr nicht überdeckt Friedrich-Alexander-Universität Erlangen-Nürnberg Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-3 M. Philippsen 5.1 Sichtbarkeit in Java Algorithmik 1, WS 2004/05, Folie 5-4 M. Philippsen 5.1 Sichtbarkeit in Java Schnittstelle („interface“) Klasse („class“) Schnittstelle („interface“) Dienst Dienst Algorithmen und Datenstrukturen y Die Referenz kann aber nur auf ein Objekt verweisen. y Wird ihr ein Objekt zugewiesen, so muss dessen Klasse die Schnittstelle implementieren. implements Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-5 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. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-6 M. Philippsen 5.1 Sichtbarkeit in Java 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 Taktgeber { long leseZeitInSekunden(); } class Uhr implements Taktgeber { ... long leseZeitInSekunden() { return (stunden*3600)+(minuten*60); } ... } Taktgeber t = new Uhr(); long l = 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 2004/05, Folie 5-7 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 ... und ohne Modifikator? s.u. Methode möglich ist. public class Uhr { // Zugriff auf Attribute von außen nicht möglich private long minuten; private long stunden; // Zugriff von außen nur über Methoden möglich public Uhr() { ... } public void setzeZeit(long std, long min) { ... } ... } Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-8 M. Philippsen 5.2 Modularität 5.2 Modularität Modul Paket („package“) 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. 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: Modularisierung Eine Modularisierung eines Systems erfolgt zum Zwecke der Übersichtlichkeit, Arbeitsteilung, Wiederverwendung, ... y java.lang y uhren y com.apple.quicktime.v2 y 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 2004/05, Folie 5-9 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-10 M. Philippsen 5.2 Modularität 5.2 Modularität Bei der Klassendeklaration kann das Paket, in das die Klasse kommen soll, mit package angegeben werden Klassenbibliothek („library“) 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 uhren; selben Paket. Daher interface Taktgeber { ist Name bekannt. long leseZeitInSekunden(); } package uhren; public class Uhr implements Taktgeber { ... } Zur Verwendung ohne import: qualifizierten Name verwenden. uhren.Taktgeber t = new uhren.Uhr(); import uhren.*; Taktgeber t = new Uhr(); y java.awt y java.io y java.lang y java.net y java.sql y java.util y javax.swing Klassen für GUIs (Abstract Window Toolkit) Ein-/Ausgabe in Dateien o.ä. Zentrale Klasse von Java (z.B. Object) Verwaltung von Netzwerkverbindungen Datenbankanbindung Nützliche Klassen (z.B. Kalender, Listen) Graphische Oberfläche Import macht Namen aus Paket bekannt; Kurzform dann nutzbar. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-11 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: Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-12 M. Philippsen 5.2 Modularität Als final deklarierte Klassen dürfen keine Unterklassen haben. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-13 Unterklassen Gemäß Zugreifbarkeit d. enthaltenden Klasse Paket Unterklassen Klasse Unterklassen Klassenname Methode Attribut Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Attribut-/Methodenname final : nicht überschreibbar Algorithmik 1, WS 2004/05, Folie 5-14 5.2 Modularität 5.2 Modularität Zugriffsbeschränkungen für Methoden/Attribute (textuell) classpath 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 public Klassen-/Schnittstellenname Unterklassen protected protected Klasse public (ohne) Unterklassen Sofern die enthaltende Klasse erreichbar ist: global private Paket 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). Zugriffsbeschränkungen (2) (ohne) Unterklassen Der Name von Klassen/Schnittstellen, protected global public Zugriffsbeschränkungen (1) (ohne) 5.2 Modularität Ü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 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-15 //Unix Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen 5.3 Klassenhierarchien Algorithmik 1, WS 2004/05, Folie 5-16 M. Philippsen 5.3 Klassenhierarchien Überschreiben von Methoden („method overriding“) 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 TaktgeberMillisekunden extends 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 2004/05, Folie 5-17 M. Philippsen 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 Uhr { ... public void anzeigen() {} } class AnalogUhr extends Uhr { ... // Selbe Signatur wie in Oberklasse public void anzeigen() { super.anzeigen(); // führt Code von Uhr.anzeigen()aus ... } } Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-18 M. Philippsen 5.3 Klassenhierarchien 5.3 Klassenhierarchien Überschreiben versus Überladen Abstrakte Klasse in Java („abstract class“) Ü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: 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 Statische Methoden können nicht überschrieben werden (wohl aber verdeckt Æ nächster Abschnitt.) Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-19 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 class Uhr { ... abstract void anzeigen(); } class AnalogUhr extends Uhr { ... void 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 M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-20 M. Philippsen 5.3 Klassenhierarchien 5.4 Polymorphie und Typsicherheit Wurzel der Hierarchie 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 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() à 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 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 2004/05, Folie 5-21 y Entstehung polymorpher Operationen durch Überladen à 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 M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-22 5.4 Polymorphie und Typsicherheit 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 Polymorphe Variablen in typsicheren Sprachen 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 c; //statischer Typ von c: Object c = new Uhr(); //dynamischer Typ von c: Uhr c.anzeigen(); //Nicht typsichere Sprachen führen zur //Laufzeit die Methode anzeigen der Klasse //Uhr (dynamischer Typ von o) aus. 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 c = new Uhr(); //statischer Typ von c: Uhr c = new AnalogUhr(); //dynamischer Typ von c: AnalogUhr // Typsicherheit: // Alle Methoden von Uhr können auf c aufgerufen werden c.anzeigen() //die anzuwendende Implementierung //wird zur Laufzeit 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.) 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 2004/05, Folie 5-23 M. Philippsen Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-24 M. Philippsen 5.4 Polymorphie und Typsicherheit 5.4 Polymorphie und Typsicherheit Dynamisches Binden („late binding“) Statisches Binden 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. Während Instanzmethoden in Java dynamisch gebunden werden, werden Klassenmethoden (static) statisch gebunden. y Bei Mehrfachvererbung nicht eindeutig, daher in Java nicht zugelassen. Uhr c = new Uhr(); c.setzeZeit(11, 42); c.anzeigen(); // Implementierung in Uhr // Implementierung in Uhr c = new AnalogUhr(); c.setzeZeit(11, 42); c.anzeigen(); // Implementierung in Uhr // Implementierung in AnalogUhr Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-25 class Super { static String greeting() { return "Goodnight"; } String name() { return "Richard"; } } class Sub extends Super { static String greeting() { return "Hello"; } String name() { return "Dick"; } Statischer Typ: Super } class Test { Dynamischer Typ: Sub public static void main(String[] args) { Super s = new Sub(); System.out.println(s.greeting() + ", " + s.name()); } } Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Liefert: „Goodnight, Dick“ Algorithmik 1, WS 2004/05, Folie 5-26 M. Philippsen 5.4 Polymorphie und Typsicherheit 5.4 Polymorphie und Typsicherheit Klasse versus Typ Typumwandlung („casting“) Typ Zu welcher Klasse ein konkretes Objekt gehört, lässt sich mit instanceof überprüfen. 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 2004/05, Folie 5-27 Uhr c; ... if (c instanceof 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 c; sichergestellt, dass diese ... Typwandlung korrekt ist. if (c instanceof DigitalUhr) { DigitalUhr digital = (DigitalUhr)c; ... } M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 5-28 5.4 Polymorphie und Typsicherheit 5.4 Polymorphie und Typsicherheit Typumwandlung am Beispiel Überschreiben versus Verdecken public class UhrenKonfiguration { public static Uhr konfigurieren(Uhr c) { if (c instanceof AnalogUhr) { AnalogUhr analog = (AnalogUhr)c; analog.setzeZifferblattfarbe(java.awt.Color.blue); return analog; } else if (c instanceof DigitalUhr) { DigitalUhr digital = (DigitalUhr)c; digital.setzeSchriftgroesse(30); return digital; } else { return c; DigitalUhr-spezifische } Methoden werden aufgerufen. } } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-29 digital hat anderen statischen Typ als c. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen 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 überschrieben 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 M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-30 M. Philippsen 5.4 Polymorphie und Typsicherheit 5.5 Beispiel Überschreiben versus Verdecken am Beispiel Implementierung der Klasse Uhr (1) package uhren; class Super { String hi = „Hi"; String name() { return "Richard"; } import java.util.Date; import uhren.Taktgeber; import uhren.TimeZone; } class Sub extends Super { String hi = „Hello"; String name() { return "Dick"; } } Super s = new Sub(); s.hi //Hi ((Sub)s).hi //Hello ((Super)s).hi //Hi s.name(); //Dick ((Sub)s).name() //Dick ((Super)s).name() //Dick Auch beim Zugriff auf Instanzvariablen wird statisch gebunden. public Uhr() { seriennummer = zaehler; zaehler++; } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-31 public abstract class Uhr implements Taktgeber { private static long zaehler = 0; private long seriennummer; private long minuten; private long stunden; private TimeZone zeitzone = new TimeZone("UTC"); private final Date herstellungsdatum = new Date(); Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-32 5.5 Beispiel 5.5 Beispiel Implementierung der Klasse Uhr (2) Implementierung der Klasse Uhr (3) ... public Uhr(long min) { this(); stunden = min / 60; minuten = min % 60; } ... public void setzeZeitZone(TimeZone tz) { if (tz == null) { return; } zeitzone = tz; } public TimeZone leseZeitZone() { return zeitzone; } ... public abstract void anzeigen(); public void setzeZeit(long std, long min) { stunden = std; minuten = min; } public void setzeZeit(long std) { setzeZeit(std, 0); } public long leseZeitInSekunden() { return (stunden * 3600) + (minuten * 60); } } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-33 M. Philippsen Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-34 5.5 Beispiel 5.5 Beispiel Abgeleitete Klasse AnalogUhr Abgeleitete Klasse DigitalUhr M. Philippsen package uhren; package uhren; import java.awt.Color; import uhren.Uhr; import uhren.Uhr; public class AnalogUhr extends Uhr { private Color zifferblattfarbe; public class DigitalUhr extends Uhr { private int schriftgroesse; public AnalogUhr(long min) { super(min); } public DigitalUhr(long min) { super(min); } public void anzeigen() { ... } public void anzeigen() { ... } public void setzeZifferblattfarbe(Color c) { zifferblattfarbe = (c == null) ? Color.blue : c; } public void setzeSchriftgroesse(int groesse) { schriftgroesse = (groesse <= 0) ? 10 : groesse; } } } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-35 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-36 M. Philippsen 5.5 Beispiel 5.5 Beispiel Schnittstelle Taktgeber und Klasse TimeZone Klasse zur Konfiguration einer Uhr package uhren; import uhren.*; import java.awt.Color; public class UhrenKonfiguration { public static Uhr konfigurieren(Uhr c) { if (c instanceof AnalogUhr) { AnalogUhr analog = (AnalogUhr)c; analog.setzeZifferblattfarbe(Color.blue); return analog; } else if (c instanceof DigitalUhr) { DigitalUhr digital = (DigitalUhr)c; digital.setzeSchriftgroesse(30); return digital; } else { return c; } } } package uhren; interface Taktgeber { long leseZeitInSekunden(); } package uhren; public class TimeZone { private String identifikator; public TimeZone(String id) { setzeIdentifikator(id); } public void setzeIdentifikator(String id) { identifikator = id; } } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 5-37 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 5-38 M. Philippsen