Java Programmierung mit Objektorientierte Programmierung (OOP) > Vererbung, Die Austauschbarkeit Mark Egloff 2006 1 Java Programmierung mit Lernziel Heute Abend > Sie lernen wie Objekte gezielt kompatibel werden und somit ausgetauscht werden können > Sie verstehen die Begriffe wie „Polymorphie“, „Überschreibung“ und „Schnittstelle“ > Sie können eigene Objektmodelle erarbeiten bei denen Teile einfach ausgetauscht werden können Mark Egloff 2006 2 Java Programmierung mit Vererbung und Austauschbarkeit Was bedeutet „Austauschbarkeit“ bei Objekten? > Ein Ziel heutiger Softwarentwicklung ist es die Architektur flexibel zu halten. Dies bedingt, dass die Objekte bzw. die Klassen untereinander austauschbar sind > Ein Objekt besitzt bestimmte Eigenschaften, wenn also Klassen ausgetauscht werden, so muss die neue Klasse alle Eigenschaften der alten Klasse aufweisen bzw. übernehmen um die Kompatibilität zu gewährleisten > Die Vererbung bietet hierzu die ideale Grundlage. Klassen welche voneinander abgeleitet sind, besitzen identische Eigenschaften und sind somit kompatibel zueinander Mark Egloff 2006 3 Java Programmierung mit Vererbung und Austauschbarkeit Warum „ Austauschbarkeit“? > Flexibilität Die Anforderungen ändern ständig, was Gestern noch vereinbart wurde, ist Morgen eventuell nicht mehr so. Bestehende Software muss also schnell geändert werden können > Wiederverwendung Wenn Teile austauschbar sind erhöht sich auch deren Wiederverwendungsgrad > „Plug-in“ Prinzip Neue Funktionalität soll einfach hinzu „gestöpselt“ werden können, wobei die bestehende Grundapplikation nicht angepasst werden muss Mark Egloff 2006 4 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Oft hat man in einer Applikation dieselben Anforderungen aber für verschiedene Objekte z.B. grafische Darstellung. Das Problem lässt sich dann nicht elegant lösen und man macht „copy-paste“ Quadrat Dreieck Zeichnungs Appl Kreis Mark Egloff 2006 5 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Die Objekte sind „ähnlich“. Sie besitzen zum Teils identische Eigenschaften aber auch nur „ähnliche“ Dreieck Kreis Quadrat radius mittelPunkt farbe punktA, punktB, punktC mittelPunkt farbe seite mittelPunkt farbe draw() draw() draw() Mark Egloff 2006 Identische & Ähnliche Eigenschaften 6 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Lösungsansatz: Alle identischen Eigenschaften werden in eine Basisklasse „Figur“ ausgelagert. Trotzdem besitzt jede Figur weiterhin eine ähnliche Methode „draw()“ die aber für jede unterschiedlich ist Figur mittelPunkt farbe Kreis Dreieck Quadrat radius punktA, punktB, punktC seite draw() draw() draw() Mark Egloff 2006 Ähnliche Eig. 7 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Kreis & Quadrat haben eine unterschiedliche „draw()“ Methode > Dieser Methodenaufruf muss im Fenster hier 2 mal bzw. für jede Figurart unterschiedlich implementiert werden Kreis Figur mittelPunkt farbe radius benützt draw() Zeichnungs Appl draw() Quadrat seite draw() draw() Mark Egloff 2006 8 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Für jede Figur müssen wir ein Attribut und ein Methodenaufruf implementieren class ZeichnungsAppl extends Frame { private Kreis kreis; private Quadrat quad; 2 Datentypen public void paint(Graphics g) { kreis.draw(g); 2 x Methodenaufruf quad.draw(g); } } Mark Egloff 2006 9 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Einer geht ja immer noch. Mit jeder neuen Figurart wird die Zeichnungsapplikationsklasse grösser und ständig unhandlicher Dreieck benützt Viereck Vieleck ZeichnungsAppl Quadrat Oval Rhombus Diamant Kreis Bild Freihand Mark Egloff 2006 10 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Wunsch: Im Prinzip ist es doch egal welche Figurenart es ist, sie soll einfach aufgezeichnet werden > In einem solchen Fall reden wir von „Generalisierung“. Das hier vorliegende Problem soll mittels Austauschbarkeit gelöst werden Zeichnungs Appl draw() draw() Spezialisierte Figur Generelle Figur Mark Egloff 2006 11 Java Programmierung mit Vererbung und Austauschbarkeit Das Substitutionsprinzip (1/4) – Rückwärtskompatibilität > Bei Vererbung haben wir gesehen, dass Klassen von anderen Klassen ihre Eigenschaften erben können. Somit sind abgeleitete Klassen kompatibel zu deren Basisklassen. > Diese Regel wurde in Java bei den Referenzen berücksichtigt. Ein Objekt bzw. seine Referenz kann den Typ der Basisklasse annehmen. Die Referenz ist rückwärtskompatibel z.B.: Rückwärtskompatibilität bei Vererbung Kreis k1 = new Kreis(); Figur f1 = k1; Figur Figur f2 = new Quadrat(); Kreis k2 = new Figur(); Compilerfehler Mark Egloff 2006 Kreis Quadrat 12 Java Programmierung mit Vererbung und Austauschbarkeit Das Substitutionsprinzip (2/4) – Rückwärtskompatibilität > Wird das Objekt einer Referenz der Basisklasse zugewiesen, benimmt sich das Objekt wie wenn es eine Instanz der Basisklasse wäre > Es kann zu diesem Zeitpunkt nicht mehr direkt auf die speziellen Eigenschaften des Objektes zugegriffen werden z.B.: Aufruf spezieller Eigenschaften so nicht mehr möglich Kreis k = new Kreis(); Figur f = k; f.setRadius( 2.5f ) ); Figur Kreis Compilerfehler Mark Egloff 2006 13 Java Programmierung mit Vererbung und Austauschbarkeit Das Substitutionsprinzip (3/4) – explizites Casting > Der Compiler gestattet bei komplexen Datentypen nur die Rückwärtskompatibilität als direkte Typumwandlung > Will man dennoch eine Referenz absichtlich einen anderen Typ zuweisen so muss dies mit einem expliziten Casting geschehen Der Interpreter überwacht ob die Typen kompatibel sind und löst eine ClassCastException aus falls nicht. Falsches Casting ist der 2. meiste Laufzeitfehler !!! z.B.: Explizites Casting bei komplexen Datentypen Figur f = new Kreis(); Kreis k = (Kreis) f; funktioniert aber gefährlich Quadrat q = (Quadrat) f; Laufzeitfehler !!! Mark Egloff 2006 14 Java Programmierung mit Vererbung und Austauschbarkeit Das Substitutionsprinzip (4/4) – „instanceof“ Operator > Java bietet einen Operator um zu prüfen vom welchen Typ das hinterlegte Objekt tatsächlich ist, den „instanceof“ Operator. > Dieser sollte immer eingesetzt werden bevor ein explizites Casting durchgeführt wird. Syntax: booleanValue = ReferenzName instanceof ClassName z.B.: Rückwärtskompatibilität bei Vererbung Figur f = new Kreis(); if ( f instanceof Kreis ) { System.out.print("Ich bin ein Kreis, Casting ok"); Kreis k = (Kreis) f; } Mark Egloff 2006 15 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Das Substitutionsprinzip erlaubt uns schon den ersten Teil zu lösen. Trotzdem können wir es noch nicht ganz vereinfachen Dreieck Viereck Vieleck Quadrat Oval Rhombus Diamant Kreis Freihand Pattern ? Mark Egloff 2006 benützt Zeichnungs Appl Figur 16 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Wir können zwar nun jede Figur mit dem gleichen Typ handhaben, müssen aber immer noch explizit Casten class ZeichnungsAppl extends Frame { private Figur f; nur noch 1 Datentyp public void paint(Graphics g) { if ( f instanceof Kreis)(f (Kreis)).draw(g); if ( f instanceof Quadrat)(f (Quadrat)).draw(g); } Immer noch 2 x Methodenaufruf } Mark Egloff 2006 17 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus (1/4) > Um das Prinzip der Austauschbarkeit und Kompatibilität zu vervollständigen wurde in der Objektorientierung ein weiterer Mechanismus eingeführt, der „Polymorphismus“ > Polymorph = vielgestaltig („mehrere Formen“) > Biologie: Unterschiedliche Formen von Lebewesen derselben Art > Chemie: Stoffe die abhängig der Umgebung verschiedene Formen annehmen z.B. Aggregatszustand > In der OO Welt bedeutet es, dass stets die konkrete Eigenschaft des Objektes aufgerufen wird, auch dann wenn das Objekt vorgibt von einer anderen Klasse bzw. Typ zu sein Mark Egloff 2006 18 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus (2/4) – Überschreibung v. Methoden > Von Überschreibung reden wir dann, wenn in der Basisklasse sowie in der abgeleiteten Klasse dieselben Eigenschaften nochmals definiert werden z.B.: Überschreibung der Methode „umfang()“ u. „draw()“ class Figur { public float umfang() {...} class Kreis extends Figur { public float umfang() {...} public void draw(Graphics g) {...} } public void draw(Graphics g) {...} } Mark Egloff 2006 19 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus (3/4) – Überschreibung v. Methoden > Es stellt sich nun die Frage, was passiert wenn im Falle der Substitution eine überschriebene Eigenschaft aufgerufen wird? z.B.: Aufruf der Methode „umfang()“ Figur f = new Figur(); f.umfang(); Figur.umfang() Kreis k = new Kreis(); k.umfang(); Kreis.umfang() Figur f2 = new Kreis(); f2.umfang(); // substitution ??? In einem solchen Fall wird immer die Methode des eigentlichen Typs aufgerufen „Kreis.umfang()“ Mark Egloff 2006 20 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus (4/4) – Überschreibung v. Methoden > Das Prinzip des Polymorphismus ist der Schlüssel zu flexiblen Softwarearchitekturen > Die Basisklasse bildet eine grundlegende Schnittstelle, wobei die abgeleiteten Klassen sich nachher „anstöpseln“ können > Man spricht auch von „dynamic“, „late“ oder „runtime binding“ da erst zur Laufzeit entschieden wird welche Funktionalität aufgerufen wird PluginA method() PluginB Interface method() Application method() method() Mark Egloff 2006 21 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Wir wenden nun das Prinzip des Polymorphismus auf unsere Zeichnungsapplikation an. Die Methode „draw()“ wird in allen FigurKlassen implementiert Kreis radius draw() Quadrat seite Figur mittelPunkt farbe draw() benützt Zeichnungs Appl draw() draw() Mark Egloff 2006 22 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Nun können wir jedes Figur-Objekt als Figur handhaben und sich selber aufzeichnen lassen. Die Zeichnungsapplikation weiss nun nicht mehr das es spezielle Figurarten gibt class ZeichnungsAppl extends Frame { private Figur f; nur noch 1 Datentyp public void paint(Graphics g) { f.draw(g); } nur noch 1 Methodenaufruf } Mark Egloff 2006 23 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus – Vorgehen bei der Umsetzung 1. Identifikation eines Musters wo ständig ähnliche Eigenschaften verschiedener Objekte verwendet werden 2. Gemeinsame Basisklasse schaffen 3. Dieselbe Eigenschaften in allen verwandten Klassen überschreiben 4. Anstelle der abgeleiteten Klassen nur noch die Basisklasse in der Applikation verwenden Mark Egloff 2006 24 Java Programmierung mit Vererbung und Austauschbarkeit Der Polymorphismus – weitere Beispiele > Polymorphismus eignet sich überall dort wo eine gemeinsame Schnittstelle geschaffen werden muss, jedoch unterschiedliche Variationen / Ausprägungen existieren > z.B. Dateisystem: File, Verzeichnis, ZipDatei, TARDatei > z.B. Eingabeaufforderung: Alle Befehle wie copy, delete, move > z.B. Verschlüsselung: verschiedene Algorithmen wie DES, RSA > z.B. Multimedia: Player Applikation für MP3, WMA, MPEG, DIVX > … Mark Egloff 2006 25 Java Programmierung mit Objektorientierte Programmierung (OOP) > Vererbung, Abstrakte Klassen und Interfaces Mark Egloff 2006 26 Java Programmierung mit Lernziel Heute Abend > Sie verstehen die Begriffe wie „abstrakte Klassen“, „abstrakte Methoden“ und „Interfaces“ und wofür diese eingesetzt werden > Sie wissen wie Schnittstellen bei Objekten erzwungen werden können > Sie können eigene Schnittstellen erzeugen und diese für abgeleitete Klassen vorgeben Mark Egloff 2006 27 Java Programmierung mit Abstrakte Klassen und Interfaces Warum Schnittstellen ? > Dank Schnittstellen sind wir in der Lage Softwareteile abzuspalten und austauschbar zu halten > Man kann eine Schnittstelle als einen „Vertrag“ ansehen der genau vorgibt was ich erfüllen muss um sie zu nutzen bzw. die Kompatibilität zu gewährleisten > In der OO besteht eine Schnittstelle ebenfalls aus einem Datentyp z.B. Klasse und deren Methoden. Um den Vertrag zu erfüllen, muss ich eine Klasse gemäss dessen Aufbau erzeugen und die Methoden überschreiben Mark Egloff 2006 28 Java Programmierung mit Abstrakte Klassen und Interfaces Warum Schnittstellen? > Problem: Wie weiss das bestehende System meine Klasse zu nutzen ? A funcA() MyClass B funcB() System ? myFunc() C D funcC() funcB() Mark Egloff 2006 dem System unbekannt Schicht 29 Java Programmierung mit Abstrakte Klassen und Interfaces Warum Schnittstellen? > Lösung: erzwingen von Implementationen mittels der Vorgabe einer Schnittelle z.B. durch Interfaces oder abstrakte Klassen A Interface funcA() MyClass B funcB() System InterfaceD func1() func2() C myfunc() func1() func2() D funcC() funcB() dem System bekannt Schicht Mark Egloff 2006 dem System unbekannt Schicht 30 Java Programmierung mit Abstrakte Klassen und Interfaces Warum Schnittstellen? z.B. „Interface“ mittels Vererbung, das Applet- Framework Rechteck Figur seiteA seiteB draw() draw() Interface radius java.applet.* draw() Applet init() paint() Browser Aufbau interessiert Programmierer nicht Kreis Vertrag Mark Egloff 2006 FigurenApplet Init() paint() Programmierer Aufbau interessiert Browser nicht 31 Java Programmierung mit Abstrakte Klassen und Interfaces „Leere“ Methoden, die die Schnittstelle vorgeben > Wenn wir eine Schnittstelle vorgeben wollen, so haben wir bis jetzt eine leere Methode in der Basisklasse implementiert, die dann in den abgeleiteten Klassen überschrieben wird. Diese Vorgabe von Schnittstellen kann man aber nun gezielter lösen. > In Java gibt es dazu zwei Konzepte: abstrakte Klassen und Schnittstellen (engl. interfaces). z.B.: Beispiel leere „draw()“ Methode class Figur { public void draw(Graphics g) { } } Mark Egloff 2006 32 Java Programmierung mit Abstrakte Klassen und Interfaces Modifizierer „abstract“ bei Klassen > Mittels dem „abstract“ kann in Java eine Klasse bzw. eine Methode als abstrakt definiert werden > Eine solche definierte Abstrakte Klasse kann nicht mehr instanziert werden, dient nur noch als Basisklasse. z.B.: Abstrakte Klasse „Figur“ abstract class Figur { public void draw(Graphics g) { } } z.B.: Instanzierung einer abstrakten Klasse endet in Compilerfehler Figur f = new Figur(); Mark Egloff 2006 Compilerfehler 33 Java Programmierung mit Abstrakte Klassen und Interfaces Modifizierer „abstract“ bei Methoden (1/2) > Bei Methoden bedeutet „abstract“ dass diese Methode keine Implementation besitzt, also leer ist > Zusätzlich wird aber nun erzwungen, dass diese Methode in abgeleiteten Klassen implementiert werden muss > Damit erreichen wir die Vorgabe einer „Schnittstelle“. Jeder der von meiner Klasse erben möchte, muss diese Methode implementieren > Abstrakte Methoden können nur innerhalb von abstrakten Klassen definiert werden Mark Egloff 2006 34 Java Programmierung mit Abstrakte Klassen und Interfaces Modifizierer „abstract“ bei Methoden (2/2) z.B.: abstrakte Methode in Basisklasse erzwingt implementation abstract class Figur { abstract public void draw(Graphics g); } class Kreis extends Figur { Compilerfehler } class Kreis extends Figur { public void draw(Graphics g) { ... } } Mark Egloff 2006 35 Java Programmierung mit Abstrakte Klassen und Interfaces Handhabung von abstrakten Methoden > Wenn wir von einer Klasse abstrakte Methoden erben, so haben wir zwei Möglichkeiten 1. Wir überschreiben alle abstrakten Methoden und implementieren sie. 2. Wir überschreiben die abstrakte Methode nicht. Das bedeutet: Eine abstrakte Methode bleibt in unserer Klasse, und unsere Klasse muss wiederum abstrakt sein Mark Egloff 2006 36 Java Programmierung mit Abstrakte Klassen und Interfaces Interfaces (Schnittstellen) (1/3) > Das Konzept der abstrakten Klassen und Methoden wurde weiter entwickelt, daraus entstand das Konzept der Schnittstellen > Eine Schnittstelle (interface) enthält keine Implementierungen, sondern nur Namen und Signaturen der enthaltenen Methoden. > Ein Interface kann wie eine abstrakte Klasse nicht instanziert werden > Eine Schnittstelle wird in Java wie eine Klasse implementiert, man verwendet anstelle von „class“ nun aber „interface“ z.B.: Interface „Drawable“ in Datei „Drawable.java“ interface Drawable { public void draw(Graphics g); } Mark Egloff 2006 37 Java Programmierung mit Abstrakte Klassen und Interfaces Interfaces (Schnittstellen) (2/3) > Möchte eine Klasse eine Schnittstelle verwenden, so folgt hinter dem Klassennamen das Schlüsselwort „implements“ und dann der Name der Schnittstelle. > Die Klasse verpflichtet sich nun alle Methoden der Schnittstelle zu implementieren. Sie darf aber dafür jederzeit als Instanz der Schnittstelle angesehen zu werden. > Eine Klasse darf mehrere Schnittstellen implementieren z.B.: Interface „Drawable“ in Klasse Kreis implementieren class Kreis implements Drawable { public void draw(Graphics g) { ...} } Mark Egloff 2006 38 Java Programmierung mit Abstrakte Klassen und Interfaces Interfaces (Schnittstellen) (3/3) z.B.: Handhabung eines Kreis-Objektes als Instanz der Schnittstelle Kreis k = new Kreis(); Drawable d = k; d.draw(g); > Wenn eine Klasse eine Schnittstelle implementiert, redet man oft dass Sie einen „Service“ unterstützt. Man sieht auch oft direkt im Code dass eine Instanz geprüft wird ob Sie eine Schnittstelle bzw. Service unterstützt. z.B.: Prüfen ob Service unterstützt wird und Aufruf der Funktionalität Object o = ...; if ( o instanceof Service) ((Service)o).callService(); Mark Egloff 2006 39 Java Programmierung mit Abstrakte Klassen und Interfaces Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Wir können nun anstelle der Basisklasse Figur ein Interface „Drawable“ schaffen, somit trennen wir die „draw()“ Funktionalität von der Basisklasse. Kreis Figur mittelPunkt farbe radius draw() Quadrat Drawable draw() benützt Zeichnungs Appl draw() seite draw() Mark Egloff 2006 40 Java Programmierung mit Vererbung und Austauschbarkeit Problem einer Zeichnungsapplikation Unterschiedliche Figuren mit „gleichen“ Eigenschaften > Die Zeinungsapplikation prüft ob jede Figurinstanz den Service „Drawable“ unterstützt und wenn ja ruft sie den Service auf z.B.: Figuren auf Service-Unterstützung „Drawable“ prüfen class ZeichnungsAppl extends Frame { private Figur[] fArray; public void paint(Graphics g) { for (int i=0; i<fArray.length; i++) if ( fArray[i] instanceof Drawable) ((Drawable)fArray[i]).draw(g); Überprüfen u. aufrufen }} Mark Egloff 2006 41 Java Programmierung mit Objektorientierte Programmierung (OOP) > Vererbung, „java.lang.Object“ Mark Egloff 2006 42 Java Programmierung mit Lernziel Heute Abend > Sie lernen die Basisklasse aller Objekte kennen „java.lang.Object“ > Sie wissen wie Objekte in Java verglichen und kopiert werden > Sie können eigene Klassen schreiben in denen die Grundfunktionen genutzt werden Mark Egloff 2006 43 Java Programmierung mit Die Basisklasse „java.lang.Object“ „Object“ ist die Mutter aller Oberklassen > In Java sind alle Klassen implizit von der Klasse „java.lang.Object“ abgeleitet > Somit spielt diese Klasse eine ganz besondere Rolle, da alle anderen Klassen automatisch Unterklassen sind und die Methoden erben beziehungsweise überschreiben > Diese Klasse bietet einige wichtige Grundfunktionalitäten sowie Schnittstellen um mit Objekten bzw. deren Referenzen zu arbeiten Mark Egloff 2006 44 Java Programmierung mit Die Basisklasse „java.lang.Object“ Methoden der Klasse „java.lang.Object“ Methode Beschreibung getClass() Gibt die Klasse des Objektes zurück hashCode() Gibt den Identifikationscode des jeweiligen Objekts zurück equals(Object) Vergleicht sich selbst mit einem anderen Objekt und gibt true oder false zurück toString() Gibt eine String Repräsentation des Objekts zurück notify() notifyAll() wait(int) Sperrt sich selber oder gibt sich selber als Semaphore wieder frei, benötigt für die Synchronisation mit Threads clone() Gibt eine Kopie von sich selber zurück, muss überschrieben werden finalize() Destruktor Methode, wird beim Aufruf des GC ausgeführt Mark Egloff 2006 45 Java Programmierung mit Die Basisklasse „java.lang.Object“ Alles ist ein „Object“ > Obwohl „extends java.lang.Object“ nicht explizit bei der Klassendeklaration aufgeführt ist, werden alle Klassen implizit von „Object“ vererbt > Die meisten Methoden von „Object“ können direkt verwendet werden. Einige müssen jedoch zuerst überschrieben werden > Alle Referenzen können vom Typ „Object“ gehandhabt werden z.B.: Aufruf der vererbten Methode „toString()“ Kreis k = new Kreis(); System.out.println( k.toString() ); Kreis@67315 z.B.: Kreisobjekt als „java.lang.Object“ handhaben Object o = new Kreis(); Mark Egloff 2006 46 Java Programmierung mit Die Basisklasse „java.lang.Object“ Überschreiben der Methode „toString()“ (1/2) > Die Methode „toString()“ gibt eine String Repräsentation des Objektes zurück > Standardmässig gibt die Methode den Klassennamen sowie den HashCode des Objektes zurück. Diese beiden Angaben identifizieren das Objekt > Leider helfen diese Angaben wenig um die Objekte selber zu identifizieren. Diese Methode wird deshalb oft überschrieben z.B.: Aufruf der herkömmlichen Methode „toString()“ Kreis k = new Kreis(); System.out.println( k.toString() ); Mark Egloff 2006 Kreis@67315 47 Java Programmierung mit Die Basisklasse „java.lang.Object“ Überschreiben der Methode „toString()“ (2/2) z.B.: Überschreiben der Methode „toString()“ class Kreis { private float radius; public Kreis(float radius){ this.radius = radius; } public String toString() { return "Kreis: radius = " + radius; } } z.B.: Aufruf der Methode „toString()“ Kreis k = new Kreis(2.5f); System.out.println( k.toString() ); Mark Egloff 2006 Kreis: 2.5 48 Java Programmierung mit Die Basisklasse „java.lang.Object“ Aufruf der Methode „toString()“ (1/2) > Java ruft bei String Verknüpfungen (mittels „+“) automatisch selber die „toString()“ Methode der Objekte auf z.B.: String Verknüpfung ruft „toString()“ auf Kreis k = new Kreis(2.5f); String s = "Kreis " + k; Mark Egloff 2006 ruft „k.toString()“ auf 49 Java Programmierung mit Die Basisklasse „java.lang.Object“ Aufruf der Methode „toString()“ (2/2) > „System.out.println()“ ist eine überladene Methode, sie akzeptiert auch Referenzen des Typs „java.lang.Object“ als Parameter. Man kann Ihr daher alles übergeben und sie ruft dann intern selber die „toString()“ Methode auf. z.B.: Übergabe als „Object“ und Aufruf der „toString()“ Methode class PrintStream { ... public String println(Object obj) { return obj.toString(); }} z.B.: Impliziter Aufruf der Methode „toString()“ Kreis k = new Kreis(); System.out.println( k ); ruft „k.toString()“ auf Mark Egloff 2006 50 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte vergleichen (1/3) > Um 2 Objekte miteinander zu vergleichen, wird die Methode „equals()“ verwendet. Diese Methode muss für seine eigenen Klassen überschrieben werden. Die vererbte „equals()“ Methode aus „Object“ vergleicht lediglich die Referenzen und daher nicht brauchbar! z.B.: Vergleich 2er String Objekte String s1 = new String("Hallo"); String s2 = new String("Hallo"); boolean a = s1 == s2; boolean b = s1.equals(s2); Mark Egloff 2006 false !! true 51 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte vergleichen (2/3) > Eine eigene „equals()“ Methode zu schreiben ist nicht ganz einfach und kann aufwendig werden (Abhängig von der Grösse und Spezialitäten der jeweiligen Klasse) Kleines Kochrezept: 1. Übergebene Referenz darf nicht „null“ sein 2. Überprüfen ob Referenz auf sich selber zeigt (optional) 3. Überprüfen ob Referenz vom Typ der Klasse ist 4. Casting der Referenz auf Typ der Klasse 5. Überprüfen der einzelnen Attribute. Für jedes Feld gilt 6. > falls Attribut vom elementarer Datentyp „==“ verwenden > falls komplexes Attribut, „equals()“ Methode des Attributs aufrufen Falls nötig die „equals()“ Methode der Basisklasse aufrufen Mark Egloff 2006 52 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte vergleichen (3/3) z.B.: Überschreiben der Methode „equals()“ 1. 2. 3. 4. class Kreis { private float radius; ... public boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (!(o.getClass().equals(this.getClass()))) return false; 5. if (((Kreis)o).radius != this.radius) return false; return true; } } Mark Egloff 2006 53 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte kopieren (1/4) > Um Objekte zu kopieren dient die „clone()“ Methode > Standardmässig ist die „clone()“ Methode geschützt und kann nicht für eigene Klassem verwendet werden. Hier müssen wir erst eine eigene „clone()“ Methode schreiben z.B.: Falsches und Richtiges Kopieren eines String Objektes String s1 = new String("Hallo"); keine Kopie! String s2 = s1; String copyOfs1 =(String) s1.clone(); Mark Egloff 2006 Richtige Kopie 54 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte kopieren (2/4) > Die „clone()“ Methode zu verwenden ist nicht trivial. SUN hat hier ein Konzept eingebaut welches man befolgen muss > Die „java.lang.Object.clone()“ Methode kopiert standardmässig nur alle Attribute von elementaren Datentypen. Komplexe Attribute müssen selber kopiert werden > Die „clone()“ Methode gibt „Object“ zurück. Man muss danach jeweils casten Kleines Kochrezept: 1. Bei der Klassendeklaration „implements Cloneable“ hinzufügen 2. Methode „clone()“ überschreiben, mit Rückgabetyp „Object“ 3. Neue Instanz erzeugen mit „super.clone()“ und casten 4. Falls nötig noch komplexe Attribute kopieren Mark Egloff 2006 55 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte kopieren (3/4) z.B.: Überschreiben der Methode „clone()“ 1. 2. 3. class Kreis implements Cloneable { private float radius; ... public Object clone() { Kreis kClone = (Kreis) super.clone(); return kClone; } } z.B.: Anwenden der Methode „clone()“ Kreis k1 = new Kreis(2.5f); Kreis k2 = (Kreis) k1.clone(); Mark Egloff 2006 56 Java Programmierung mit Die Basisklasse „java.lang.Object“ Objekte kopieren (4/4) > Mit diesem Konzept haben wir die Wahl was für unsere Objekte kopiert werden soll. Dies kann die Effizienz stark beeinflussen. > Man spricht auch von „Flacher“ oder „Tiefer“ Kopie > > „Flache Kopie“ nur die wesentlichsten Attribute, die zum Objekt selber gehören, werden kopiert erste Hierarchie > „Tiefe Kopie“ alle Attribute werden kopiert Alle Hierarchien Würde die Angabe des Interfaces „Cloneable“ bei der Klassendeklaration weggelassen, wird der Aufruf der Methode „clone()“ in eine „CloneNotSupportedException“ enden z.B.: Aufruf der Methode „clone()“ endet in Exception Kreis k1 = new Kreis(2.5f); Kreis k2 = (Kreis) k1.clone(); CloneNotSupportedException Mark Egloff 2006 57