Universität Stuttgart Institut für Automatisierungs- und Softwaretechnik Prof. Dr.-Ing. Dr. h. c. P. Göhner Einführung in Java, Teil 3 (Original Titel der Folien: JavaIntensivkurs am IAS) Vorlesung Informatik I, 24.11.2005, Daniel Huson © 2000, IAS 1 Überblick Teil 3: Overloading, Konstruktoren, Vererbung Ausnahmebehandlung Teil 4: Datenstreams und Dateien © 2000, IAS 2 Overloading, Konstruktoren, Vererbung Überladen von Methoden (1) Überladen von Methoden (Overloading): gleicher Methodenname, aber unterschiedliche Argumentliste (Anzahl und Typ) in Java können nur Methoden überladen werden (Operatoren-Overloading ist nicht möglich) Überladen bewirkt Vereinfachung der Schnittstelle: nur ein Methodenname muss gelernt werden, richtige Methode wird in Abhängigkeit von Argumentliste aufgerufen Wichtig: Rückgabetyp kann beim Überladen nicht zur Unterscheidung verwendet werden © 2000, IAS 3 Overloading, Konstruktoren, Vererbung Überladen von Methoden (2) Beispiel - Initialisierung mit Methoden class Rechteck1 { int x1 = 0; // Punktkoordinaten oben rechts int y1 = 0; int x2 = 0; // Punktkoordinaten unten links int y2 = 0; Rechteck initRecht(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; return this; } Rechteck initRecht(Point obLinks, Point unRechts) { x1 = obLinks.x; y1 = obLinks.y; x2 = unRechts.x; y2 = unRechts.y; return this; } } © 2000, IAS 4 Overloading, Konstruktoren, Vererbung Konstruktor (1) besondere Methodenart, die bei der Instanziierung einer Klasse (new) automatisch aufgerufen wird Konstruktoren bestimmen die Initialisierung der Objekte Ablauf der Instanziierung mit new: • Speicherplatz für Objekt reservieren • Initialisierung der Instanzvariablen mit Defaultwerten • Konstruktor-Aufruf Konstruktor-Definition: • gleicher Name wie Klasse • kein Rückgabewert! Konstruktoren können wie Methoden überladen werden Aufräumarbeiten können mit der finalize-Methode veranlasst werden (Dekonstruktor) © 2000, IAS 5 Overloading, Konstruktoren, Vererbung Konstruktor (2) Beispiel - Initialisierung mit Konstruktoren: class int int int int Rechteck { x1 = 0; y1 = 0; x2 = 0; y2 = 0; // Punktkoordinaten oben rechts // Punktkoordinaten unten links Rechteck(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } Rechteck(Point obLinks, Point unRechts) { x1 = obLinks.x; y1 = obLinks.y; x2 = unRechts.x; y2 = unRechts.y; } } © 2000, IAS 6 Overloading, Konstruktoren, Vererbung Vererbung (1) ermöglicht Hierarchisierung von Klassen übergeordnete Superklassen vererben Variablen und Methoden an Subklassen, d.h. Subklassen erben von Superklassen in Java erben alle Klassen implizit von der Klasse Object, welche allgemeingültige Verhaltensregeln definiert Klassenhierarchie: CC AA Hierarchie-Wurzel: Klasse A (in Java Klasse Object) BB abgeleitete Klasse B, erbt von A DD EE abgeleitete Klassen C, D und E erben jeweils von B und A © 2000, IAS 7 Overloading, Konstruktoren, Vererbung Vererbung (2) Vererbungsvarianten: Einfach- und Mehrfachvererbung Einfachvererbung: jede Klasse hat höchstens eine Superklasse Mehrfachvererbung: jede Klasse kann von mehreren Superklassen erben (in Java nicht erlaubt) Einfachvererbung (Baum): Mehrfachvererbung (Netz): © 2000, IAS 8 Overloading, Konstruktoren, Vererbung Vererbung (3) Beispiel: class Punkt { int x; // x-Koordinate int y; // y-Koordinate void printInfoPunkt() { System.out.println(“Punkt: “ + x + “/“ + y); } } class Pixel extends Punkt { String farbe; // Punktfarbe } void printInfoPixel() { System.out.println(“Pixel: “ + x + “/” + y); System.out.println(“Pixelfarbe: “ + farbe”); } Subklasse erbt automatisch alle Variablen und Methoden der Superklasse Regel: Ableiten macht nur Sinn, wenn eine allgemeingültige Klasse durch neue Methoden/Variablen erweitert/verändert werden soll © 2000, IAS 9 Overloading, Konstruktoren, Vererbung Vererbung (4) Wie funktioniert ein Methodenaufruf in Java? • zunächst in der aktuellen Klasse nach passender Methodendefinition suchen • falls Suche in aktueller Klasse erfolglos, Aufruf in der Klassenhierarchie nach oben weiterreichen Konsequenzen: • bereits definierte Methoden können in Subklassen ohne Codeduplizierung wiederverwendet werden • die Methode einer Superklasse kann in der Subklasse entweder unverändert übernommen oder überschrieben/redefiniert werden Wichtig: Überschreiben (Signatur gleich) nicht mit Überladen (Argumentliste unterschiedlich) verwechseln! © 2000, IAS 10 Overloading, Konstruktoren, Vererbung Methoden überschreiben (1) Methoden mit identischer Signatur wie in Superklasse, aber unterschiedliche Methodenkörper Warum überschreibt man Methoden? • um geerbte Methoden vollständig zu ersetzen • um geerbte Methoden zu erweitern Beispiel: class PrintKlasse { int x = 0; int y = 1; void drucken() { System.out.println(“x, y = “ + x + “ “ + y); } } class PrintSubKlasse extends PrintKlasse { int z = 3; void drucken() { // geerbte Methode ersetzen System.out.print(“x, y, z = “ + x + “ “ + y + “ “ + z); } } © 2000, IAS 11 Overloading, Konstruktoren, Vererbung Methoden überschreiben (2) das Schlüsselwort super ermöglicht den Zugriff auf die “verdeckte” Orginalmethode in der Superklasse Beispiel: class PrintKlasse { int x = 0; int y = 1; void drucken() { System.out.println(“x, y = “ + x + “ “ + y); } } class PrintSubKlasse extends PrintKlasse { int z = 3; void drucken() { // geerbte Methode erweitern super.drucken(); System.out.print(“z = “ + z); } } © 2000, IAS 12 Overloading, Konstruktoren, Vererbung Konstruktoren überschreiben? Konstruktoren werden grundsätzlich nicht vererbt und können somit auch nicht überschrieben werden beim Konstruktoraufruf für ein Objekt werden automatisch alle Konstruktoren der Superklassen aufgerufen mit dem Schlüsselwort super wird der “richtige” Konstruktor der Superklasse aufgerufen Beispiel: class BenannterPunkt extends Point{ String name; BenannterPunkt(int x, int y, String name) { super(x, y); this.name = name; } } © 2000, IAS 13 © 2000, IAS 14 Overloading, Konstruktoren, Vererbung Zugriffsrechte für Klassen in Java wird die Kapselung (OO-Hauptelement) mit Hilfe von Schlüsselwörtern (modifier) verwirklicht für Klassen stehen zwei Zugriffsebenen zur Verfügung: public und package public mit public definierte Klassen sind für alle anderen Klassen sichtbar package ohne zusätzliche Angaben sind Klassen automatisch nur innerhalb des gleichen Pakets sichtbar (kein packageSchlüsselwort notwendig) © 2000, IAS 15 © 2000, IAS 16 Overloading, Konstruktoren, Vererbung Zugriffsrechte für Methoden und Variablen (1) in Java stehen für Methoden und Variablen 4 Zugriffsebenen zur Verfügung: public, package, protected und private das Zugriffs-Schlüsselwort steht vor dem Methoden/Variablen-namen und wird jeweils einzeln vereinbart public mit public definierte Methoden/Variablen sind für alle anderen Klassen sichtbar, d.h. es gibt keine Zugriffsbeschränkungen Beispiel: public class OffeneKlasse { public int offenesInt; public String offenerString; public float offeneMethode() { ... } } © 2000, IAS 17 Overloading, Konstruktoren, Vererbung Zugriffsrechte für Methoden und Variablen (2) package mit dem package-Schlüsselwort werden Klassen in Pakete gruppiert falls explizit kein Zugriffsebene definiert wird gilt automatisch die package-Schutzebene (kein packageSchlüsselwort) alle Methoden/Variablen dieser Ebenes sind nur innerhalb des gleichen Pakets sichtbar Beispiel: package paket1; public class PaketKlasse { int paketInt = 2; String paketString = “a bis z”; } float paketMethode() { ... } © 2000, IAS 18 Overloading, Konstruktoren, Vererbung Zugriffsrechte für Methoden und Variablen (3) protected nur Elemente der gleichen und davon abgeleiteter Klassen haben Zugriff Beispiel: public class ProtectedKlasse { protected int protInt = 4; protected String pstr = “a bis z”; protected float protectedMethod() { ... } } public class GleichesPaket { public void test() { ProtectedKlasse pk = new ProtectedKlasse(); System.out.println(pk.pstr); pk.protectedMethod(); } Nicht erlaubt! } © 2000, IAS 19 Overloading, Konstruktoren, Vererbung Zugriffsrechte für Methoden und Variablen (4) private strengster Schutz: Methoden und Variablen nur innerhalb der eigenen Klasse zugreifbar im Sinne einer umfassenden Kapselung sollten Daten möglichst private deklariert werden spezielle get/set-Methoden ermöglichen den kontrollierten Zugriff auf die private-Elemente Beispiel: public class Kreis { private int x, y, radius; public int getRadius() { return radius; } public int setRadius( int value ) { radius = value; return radius; } } © 2000, IAS 20 Overloading, Konstruktoren, Vererbung Zugriffsrechte im Überblick Klasse für alle Klassen (auch außerhalb des Pakets) nur für Klassen innerhalb des Pakets public - Methode/ Variable für alle Klassen (auch außerhalb des Pakets) nur für Klassen innerhalb des Pakets public protected private abgeleitete Klassen und Klassen innerhalb des Pakets nur für eigene Klasse Empfehlung: • Datenelemente (Variablen) private • Methoden protected • get-/set-Methoden für Zugriff auf private Daten definieren © 2000, IAS 21 Overloading, Konstruktoren, Vererbung final-Modifier (1) mit dem final-Schlüsselwort können zusätzl. Einschränkungen definiert werden, die Compiler-Optimierungen ermöglichen Klassen mit final deklarierte Klassen können nicht abgeleitet werden public final class FinalKlasse1 { ... } Methoden final-Methoden können in Subklassen nicht überschrieben werden public class FinalKlasse2 { public final void finalMethode() { ... } } alle Methoden in einer final-Klasse sind final alle private-Methoden sind implizit final © 2000, IAS 22 Overloading, Konstruktoren, Vererbung final-Modifier (2) Variablen mit final werden in Java Konstanten deklariert public class FinalKlasse3 { public final int CONSTINT = 243; public final String CSTR = “Kaffee”; } der konstante Wert wird während der Deklaration zugewiesen lokale Variablen können nicht als final deklariert werden while( summe <= 10 ) { ... final int LOCALINT; ... } Nicht erlaubt! © 2000, IAS 23 Overloading, Konstruktoren, Vererbung abstract-Modifier abstrakte Klassen sind ein Design-Element: mit abstract gekennzeichnete Klassen können nicht instanziiert werden in einer abstrakten Klasse werden Methoden ohne Implementierung (Methodenkörper) mit abstract gekennzeichnet Beispiel: public abstract class AbstrakteKlasse { int i; public void tuWas() { ... } public abstract void absMethode(); } Object a = new AbstrakteKlasse(); © 2000, IAS Nicht erlaubt! 24 Beispiel abstrakte Klasse: abstract class Geraet { int seriennummer; int getSeriennummer () { return seriennummer; } void setSeriennummer (int n) { seriennummer=n; } abstract void einSchalten (); } © 2000, IAS bis hier 25 Schnittstellen Problem: Fahrzeug “Fahrzeughierarchie” Wasserfahrzeug Landfahrzeug PKW Ziel: verwenden, ohne Lösung: Motorrad Amphibienfahrzeug Schiff gemeinsames Verhalten Codeduplizierung a) Mehrfachvererbung: in Java nicht erlaubt b) Schnittstellen © 2000, IAS 26 Fahrzeughierarchie © 2000, IAS 27 Fahrzeughierarchie interface Fahrzeug { int getMaxGeschwindigkeit (); int getGewicht (); Color getFarbe (); } interface Landfahrzeug extends Fahrzeug { int getAnzahlRader (); } interface Wasserfahrzeug extends Fahrzeug { int getVerdraengung (); } class Amphibienfahrzeug implements Landfahrzeug, Wasserfahrzeug { int getMaxGeschwindigkeit () { return 55; } int getGewicht () { return 1000; } ... } © 2000, IAS 28 Overloading, Konstruktoren, Vererbung Schnittstellen (1) Problem: “Tierhierarchie” Tier Tier Säugetier Säugetier Merkmale: + lebende Jungen + Fell Vogel Vogel + legen Eier + Schnabel Wohin gehört das Schnabeltier (Fell & Schnabel)? Ziel: gemeinsames Verhalten verwenden, ohne Codeduplizierung Lösung: a) Mehrfachvererbung: in Java nicht erlaubt b) Schnittstellen © 2000, IAS 29 Overloading, Konstruktoren, Vererbung Schnittstellen (2) Schnittstelle: Sammlung von abstrakten Methodendeklarationen und Konstanten ohne Methodenimplementierungen und Instanzvariablen Definition Deklaration mit Schlüsselwort interface Schnittstellenmethoden sollten als public abstract und Konstanten als public static final deklariert sein Schnittstellen gehören zu Paketen und können andere Pakete importieren Schnittstellen können mit extends in Hierarchien organisiert werden public interface Iface { public static final int incr = 10; public static final long maxNum = 1000000; public abstract void doIt(); } © 2000, IAS 30 Overloading, Konstruktoren, Vererbung Schnittstellen (3) Anwendung Schnittstellen werden durch das Schlüsselwort implements in eine Klassendefinition eingebunden alle in der Schnittstelle deklarierten Methoden müssen von der einbindenden Klasse implementiert werden eine Klasse darf mehrere Schnittstellen implementieren Regel: Schnittstellen können mit wenigen Ausnahmen überall dort verwendet werden, wo auch Klassen verwendet werden Beispiel: public interface Fruchtartig { public abstract void verfallen(); public abstract void auspressen(); } public class Frucht implements Fruchtartig { private Color farbe; public void verfallen() { ... } public void auspressen() { ... } } © 2000, IAS 31 Überblick Teil 3: Overloading, Konstruktoren, Vererbung Ausnahmebehandlung Teil 4: Datenstreams und Dateien © 2000, IAS 32 Ausnahmebehandlung Ausnahmefälle (1) Design und Implementierung von Klassen und Methoden beschreiben normalen Ablauf, nicht jedoch den Ablauf in “Ausnahmefällen” Java bietet die Möglichkeit, Ausnahmefälle zu deklarieren und zu behandeln, d.h. ungewöhnliche Situationen werden handhabbar, ohne den normalen Quellcode aufzubrechen Ausnahmefälle sind Objekte, die in einer Klassenhierarchie organisiert sind Java kennt drei Arten von Ausnahmefällen, die alle von der Superklasse Throwable abgeleitet sind: • Ausnahmen (Exception): ClassNotFound, FileNotFound • Laufzeitausnahmen (RuntimeException): IndexOutOfBounds • Fehler (Error): OutOfMemory, StackOverflow © 2000, IAS 33 Ausnahmebehandlung, Beispiel Rational.java © 2000, IAS 34 Ausnahmebehandlung, Beispiel Rational.java class Rational { int zaehler; int nenner; ... Rational (int p,int q) throws Exception { if(q==0) throw new Exception(“q==0“); zaehler=p; nenner=q; normalize(); } ... } © 2000, IAS 35 Ausnahmebehandlung Ausnahmefälle (2) Ausnahmefälle deklarieren Ausnahmefälle, die innerhalb einer Klasse oder Methode auftreten können, werden mit dem throws-Schlüsselwort deklariert public class AusnahmeKlasse { public void ausnahmeMethode1() throws AusnameFall1 { ... } Fehler und Laufzeitausnahmen müssen nicht deklariert werden Wenn in einer Methode Ausnahmen auftreten können, müssen diese a) potentiellen Aufrufern mit der throws-Deklaration explizit bekanntgegeben werden oder b) von der Methode selbst gehandhabt werden © 2000, IAS 36 Ausnahmebehandlung Ausnahmefälle (3) Ausnahmen handhaben (Exception Handling) Ausnahmefälle werden mit den try/catch-Anweisungen gehandhabt public void methode2() { AusnahmeKlasse aKlasse = new AusnahmeKlasse(); try { // ausnahmeträchtiger Code aKlasse.ausnahmeMethode1(); } catch ( AusnahmeFall1 ) { ... } } eingetretene Ausnahmen werden in der MethodenAufrufhierarchie nach oben gereicht, bis sie a) behandelt werden oder b) das Programm mit einer Fehlermeldung abgebrochen wird © 2000, IAS 37 Ausnahmebehandlung, Beispiel Rational.java © 2000, IAS 38 Ausnahmebehandlung, Beispiel Rational.java ... ... int p=5; int q=0; Rational r; try { r=new Rational(p,q); System.out.println(“ok“); } catch (Exception ex) { System.out.println(“Fehler:“+ex.getMessage()); } Ausgabe: Fehler: q==0 © 2000, IAS 39 Ausnahmebehandlung, Beispiel Rational.java public class ZeroZaehlerException extends Exception { } ------------------... int p=5; int q=0; Rational r; try { r=new Rational(p,q); System.out.println(“ok“); } catch (ZeroZaehlerException ex) { System.out.println(“Fehler:“+ex.getMessage()); } ... © 2000, IAS 40 Ausnahmebehandlung Javaprogrammierung: Ausnahmen stehts durch Exceptions behandlen, nicht durch Fallunterscheidungen im Code. schlecht gut Rational (int p,int q) throws Exception { if(q==0) throw new Exception (“q==0“); zaehler=p; nenner=q; normalize(); } © 2000, IAS Rational (int p,int q) { if(q==0) {p=0; q=1;} zaehler=p; nenner=q; normalize(); } 41 Ausnahmebehandlung Ausnahmefälle (4) Ausnahmen auswerfen mit Hilfe der throw-Anweisung werden Ausnahmen “ausgeworfen” public class AusnahmeKlasse { public void ausnahmeMethode1() throws AusnahmeFall1 { // normaler Code if( ungewoehnlicherVorfall() ) { throw new AusnahmeFall1(); // hier wird die Ausfuehrung abgebrochen } } } tritt eine Ausnahme ein, so werden alle Anweisungen hinter der throw-Anweisung ignoriert © 2000, IAS 42 OO-Konzepte & Ausnahmebehandlung Zusammenfassung Überladen von Methoden Konstruktoren Vererbung Überschreiben von Methoden/Konstruktoren Zugriffsrechte für Klassen, Methoden und Variablen final-Modifier abstrakte Klassen und Methoden Schnittstellen Behandlung von Ausnahmen © 2000, IAS 43