Praktische Informatik II

Werbung
Praktische Informatik II
Problemlöseverfahren
Softwareentwurf
Dozent:
Prof. Thomas Stricker, Ph.D.
Unterrichtssprache:
Deutsch
Programmiersprache:
Java
Englisches Textbuch:
Weiss: Datenstructures and
Problem Solving with Java
ISBN
Eidgenössische
Technische Hochschule
Zürich
Praktische Informatik II
7.5.02 - 1
© Stricker/Mattern
Objektorientiertes Programmieren
Weltsicht: Die Welt besteht aus verschiedenen interagierenden "Dingen", welche sich klassifizieren lassen.
Ding 1
Typ B
Ding 2
Typ B
Ding 3
Typ A
Ding 4
Typ A
Ding 5
Typ B
Ziel: Betrachteten Weltausschnitt strukturkonsistent mit
kommunizierenden Objekten abbilden und modellieren.
Simulationssprache SIMULA war die erste
objektorientierte Programmiersprache (1967)
Objekte:
- sind autonome gekapselte Einheiten eines bestimmten Typs
- haben einen eigenen Zustand (= lokale Variablen)
- besitzen ein Verhalten (wenn sie aktiviert werden)
- bieten anderen Objekten Dienstleistungen an
- Durchführung von Berechnungen
- Änderungen des lokalen Zustandes
- Zurückliefern von Variablenwerten oder Berechnungsergebnissen
- Allgemein: "Reaktion" auf Aufruf einer Methode
102
Praktische Informatik II
7.5.02 - 2
© Stricker/Mattern
Objektorientierter Softwareentwurf
- Strukturierung der Problemlösung in eine Menge
kooperierender Objekte
- Entwurf der Objekttypen, dabei ähnliche Objekte zu
Klassen zusammenfassen
- Herausfaktorisierung gemeinsamer Aspekte verschiedener Klassen ==> Hierarchie festlegen, Klassenbibliothek
- Festlegung einzelner Dienstleistungen (--> Methoden)
- Entwurf der Objektbeziehungen ("Protokoll")
- Feinplanung der einzelnen Methoden, Festlegung
der Klassenattribute etc.
- Strukturierung und Implementierung der Methoden
(klassisches Programmieren im Kleinen)
103
Praktische Informatik II
7.5.02 - 3
© Stricker/Mattern
Objektorientiertes Modellieren
- Es sollte bereits in frühen Phasen des Softwareentwurfs
(Problemanalyse, Anforderungsdefinition) das
Objektparadigma verwendet werden
- Leitlinie: Betrachteten Ausschnitt der Welt "strukturkonsistent" mittels interagierende Objekte abbilden
- Problem: Geeignete Objekte und Typen im
Anwendungsbereich identifizieren
- Aufgabe: Relevante Merkmale der Objekte identifizieren
- Aufgabe: Interaktionsmuster der Objekte analysieren
(Informationsfluss; Geflecht von Dienstleistungen)
Das objektorientierte Modellieren als Prinzip ist in
mancherlei Hinsicht eher eine "Kunst" als eine Technik
- eine eindeutige Methode gibt es nicht
- es wird eine Vielzahl von methodischen Ansätzen gehandelt, die
z.T. durch Werkzeuge und Techniken (oft "halbformaler" Art,
z.B. strukturierte graphische Diagramme) unterstützt werden
Praktische Informatik II
7.5.02 - 4
© Stricker/Mattern
Vererbung ("inheritance")
Mensch
Spezialisierung
Verallgemeinerung
Geschäftsmann
Kaufmann
Sportler
Rennfahrer
Internetprovider
Student
Sportstudent
Bäcker
Informatikstudent
Taxonomie in Form eines
Konzeptverbandes
- Spezialisierung, Verallgemeinerung
- ein Informatikstudent ist ein Mensch mit Programmierkenntnissen
- ein Rennfahrer ist ein spezieller Sportler
- Alle Merkmale, Eigenschaften... des umfassenderen
Begriffs werden auf den Unterbegriff vererbt
- ein Rennfahrer hat mehr Eigenschaften als ein (beliebiger!) Sportler
- ein Rennfahrer erbt von zwei Oberkonzepten (Mehrfachvererbung )
- Bem.: Mehrfachvererbung ("multiple inheritance") in Java nicht möglich
- Vererbungsrelation ist transitiv
- ein Bäcker hat alle Eigenschaften eines ("generischen") Menschen
- Ein Objekt (als "Begriffsinstanz") hat viele Facetten
- ein Rennfahrer kann je nach Zweckmässigkeit auch entweder nur als
Sportler oder als Geschäftsmann oder schlicht einfach als Mensch
betrachtet werden
105
Praktische Informatik II
7.5.02 - 5
© Stricker/Mattern
Klassenhierarchie als Konzeptbaum
Konzeptbaum:
Basisklasse (auch:
“Oberklasse”)
Fahrzeug
Fahrrad
Auto
Personenwagen
VW
abgeleitete Klassen
von "Fahrzeug" (auch:
“Unterklassen” oder
“erweiterte Klassen”)
Lastwagen
Ford
Entwurf eines Klassenbaumes ist wichtige
Aufgabe der Entwurfsphase beim objektorientierten Programmieren!
"is-a"-Relation
- Ein VW ist ein Personenwagen ist ein Auto ist ein Fahrzeug
- Eine Trompete ist ein Blasinstrument ist ein Musikinstrument
- Ein Fahrzeug hat Räder ==> ein Personenwagen hat Räder
Praktische Informatik II
7.5.02 - 6
© Stricker/Mattern
Abgeleitete Klassen, Redefinition
- Eine abgeleitete Klasse besitzt automatisch alle
Eigenschaften der zugehörigen Basisklasse(n).
- Konkret: Sie besitzt alle Attribute und
alle Methoden der Basisklassen.
- Ausser: Es werden einige davon unsichtbar gemacht
oder einige Methoden redefiniert.
heissen noch genauso,
tun aber etwas anderes!
- Eine abgeleitete Klasse kann zusätzliche Attribute
und Methoden definieren.
Fahrzeug:
- Radzahl
- km-Stand
"Fahrzeugteil"
eines Autos
Auto:
Personenwagen:
- Radzahl
- km-Stand
- PS
- Hubraum
"Autoteil"
eines Personenwagens
- Radzahl
- km-Stand
- PS
- Hubraum
- Beifahrerzahl
- Eine Methode "Berechne_Steuer" lässt sich
nicht für alle Fahrzeuge gleichermassen definieren.
==> Man würde z.B. in "Auto" eine Standardmethode
vorsehen (Benutzung von "Hubraum"), jedoch für
spezielle Fahrzeuge (z.B. Elektroautos) diese
Methode anders definieren.
Praktische Informatik II
7.5.02 - 7
107
© Stricker/Mattern
Ein Beispiel in Java
Vorfahre weiss nicht von den Erben; Er-
class Fahrzeug
be muss sich seinen Vorfahren aussuchen!
{ public int Radzahl;};
class Auto extends Fahrzeug
{ public int PS;
public float Hubraum;};
Erweiterung der Klasse
"Fahrzeug": Alles, was
in "Fahrzeug" deklariert ist, gehört damit
auch zu "Auto" (sowohl
Attribute als auch
Methoden) - mit gewissen Einschränkungen
(--> später)
class PW extends Auto
{ public int Beifahrerzahl;
void print()
{System.out.println("Radzahl: "+ Radzahl
+ Beifahrerzahl: " + Beifahrerzahl);}
};
class LW extends Auto
{ public float Zuladung; };
Auf "weiter oben"
definierte Attribute
kann ohne weiteres
zugegriffen werden diese sind Teil der
abgeleiteten Klasse!
class Beispiel {
public static void main (String args[]) {
Fahrzeug f = new Fahrzeug();
Auto a = new Auto(); Hier werden Instanzen (also
PW p = new PW();
Objekte) der verschiedensten
LW l = new LW();
Hierarchiestufe erzeugt.
p.Beifahrerzahl = 5;
p.PS = 70;
p.Hubraum = 1794;
p.Radzahl = 4;
p.print();
p.Zuladung geht
natürlich nicht!
Zugriff auf Variablen
und Methoden des
mit ’p’ bezeichneten
PW-Objektes.
Idee: Gemeinsame Aspekte herausfaktorisieren und in eine übergeordnete Klasse einbringen.
108
Praktische Informatik II
7.5.02 - 8
© Stricker/Mattern
Zuweisungskompatibilität
- Objekte von abgeleiteten Klassen können an Variablen vom Typ der Basisklasse zugewiesen werden.
- Fahrzeug f; Auto a; ... f = a;
- Variable f kann Fahrzeugobjekte speichern.
- Ein Auto ist ein Fahrzeug.
- Daher kann f auch Autoobjekte speichern.
- Die Umkehrung gilt jedoch nicht!
- a = f; ist verboten!
- Variable a kann Autoobjekte speichern.
- Ein Fahrzeug ist aber kein Auto!
"Gleichnis" zur Zuweisungskompatibilität: Auf einem Parkplatz für
Fahrzeuge dürfen Autos, Personenwagen, Fahrräder... abgestellt werden.
Auf einem Parkplatz für Fahrräder jedoch keine beliebigen Fahrzeuge!
- Merke also:
Eine Variable vom Typ "Basisklasse" darf
! auch ein Objekt der abgeleiteten Klasse enthalten!
Man nennt diese Eigenschaft auch Polymorphismus, da
eine Referenz auf Objekte verschiedenen Typs zeigen kann
(bzw. eine Variable Werte untersch. Typs haben kann).
Beispiel: Eine Variable vom Typ "Referenz auf Fahrzeug" kann
zur Laufzeit sowohl zeitweise auf PW-Objekte,
als auch zeitweise auf LW-Objekte zeigen.
Praktische Informatik II
7.5.02 - 9
109
© Stricker/Mattern
Ein Java-Beispiel
class Fahrzeug {... int Radzahl;}
class Auto extends Fahrzeug {...float Hubraum;}
class PW extends Auto ...
Fahrzeug
Fahrzeug f; Auto a; PW p;
Radzahl
... new ...
p.Hubraum = 1702; Ein PW ist ein Auto
Auto
und ein Fahrzeug
p.Radzahl = 4;
Hubraum
a = p;
f = p;
Eine Fahrzeug-Variable darf PWObjekte und Auto-Objekte speichern
f = a;
PW
/* a = f; */
/* incompatible types for =... */
Andersherum geht es nicht!
a.Radzahl = 3;
a.Hubraum = 1100;
Es wurde zwar Radzahl und Hubf = a;
raum zugewiesen; auf Hubraum
System.out.println
ist aber über f nicht zugreifbar!
(f.Radzahl);
/* System.out.println(f.Hubraum); */;
/* No variable Hubraum defined in Fahrzeug */
- f.Hubraum ist aus gutem Grund verboten: Auf f könnte
ja zufällig ein Fahrrad (ohne Hubraum!) "parken"!
- durch Umtypen kommt man aber notfalls auch über f an den Hubraum
des Auto-Objektes: System.out.println(((Auto)f).Hubraum);
- aber wenn dort "gerade" kein Auto (sondern ein Fahrrad) parkt?
Dann gibt es einen Laufzeitfehler "ClassCastException"!
- dem kann man wie folgt vorbeugen:
if (f instanceof Auto)
System.out.println(((Auto)f).Hubraum);
else System.out.println("kein Auto, kein Hubraum!");
110
Praktische Informatik II
7.5.02 - 10
© Stricker/Mattern
Polymorphie und abstrakte Methoden
- Polymorphie = "Vielgestaltigkeit"
- eine Variable kann Werte unterschiedlichen Typs annehmen
- bzw.: eine Referenz kann auf Objekte unterschiedlichen
(aber "verwandten") Typs verweisen
- Objekte unterschiedlichen Typs haben gleichnamige Methoden
Beispiel:
Methode "Flächenwert"
ist für alle Objekttypen
realisiert, jedoch unterschiedlich je nach Typ!
Geometrisches
Objekt
Ellipse
Rechteck
Kreis
Quadrat
Dreieck
- Polymorphe Liste:
Anker
next
abstract class geo_ob
{ geo_ob next;
public
abstract double flaechenwert();};
Diese Methode
für jede abgeleitete Klasse
mit sinnvoller
Semantik
versehen!
- Eine Klasse mit abstrakten Methoden muss selbst
als "abstract" deklariert werden
- Abstrakte Methoden werden von den abgeleiteten
Klassen jeweils spezifisch implementiert
Praktische Informatik II
7.5.02 - 11
111
© Stricker/Mattern
Polymorphe Liste
class Dreieck extends geo_ob
{ /* Koordinaten etc. als Attribute */
{ public double flaechenwert()
... /* bekannte Formel anwenden */
System.out.print("Dreiecksfläche:...”);}
}
}
class Kreis extends geo_ob /* ähnlich */
- Eine polymorphe Liste kann man dann z.B. so durchlaufen:
for (geo_ob z = Anker; z != null; z = z.next)
F = F + z.flaechenwert(); Alle Flächenwerte
aufaddieren
- Die Verabeitung der einzelnen Objekte kann unabhängig von ihrem eigentlichen Typ geschehen.
- In der Praxis wird eine solche "Verabeitung" i.a.
wesentlich komplexer sein als hier angedeutet.
- Es können ohne den Verabeitungsalgorithmus anzupassen neue Objekttypen als Unterklassen von "geo_ob"
eingeführt werden (z.B. ’Quadrat’).
Nur hinzufügen,
aber nichts verändern (im Idealfall) vermindert
den Wartungsaufwand beträchtlich!
- Late binding: Es wird zur Laufzeit berechnet, welche
Methode "angesprungen" wird; dies steht zur Übersetzungszeit (--> "early binding") noch nicht fest!
112
Praktische Informatik II
7.5.02 - 12
© Stricker/Mattern
Generische Methoden und
abstrakte Klassen
abstract class Sort {
abstract boolean kleiner (Sort y);
static void sort(Sort[] Tab) {
for (int i=0; i<Tab.length; i++)
for (int j=i+1; j<Tab.length; j++)
if (Tab[i].kleiner(Tab[j])) {
Sort swap = Tab[i];
Tab[i] = Tab[j];
Achtung: Es wird
Tab[j] = swap;
absteigend sortiert!
}
}
} Das einfache Sortierverfahren ("deletion sort") ist ineffizient!
- Wir fordern, dass die zu sortierenden Objekte vom Typ
einer von Sort abgeleiteten Klasse sind.
- In der abgeleiteten Klasse muss ausserdem
die Methode "kleiner" realisiert werden.
Als totale Ordnungsrelation
auf den Objekten!
- Unabhängig davon, wie die Relation "kleiner"
definiert ist, funktioniert unser Sortierverfahren!
- Das Sortierverfahren kann also bereits implementiert
(und getestet) werde, bevor überhaupt die Daten
selbst bekannt sind!
- Einmal entwickelt, kann man den Algorithmus auch
zum Sortieren anderer Datentypen verwenden!
(int, float, Brüche als rationale Zahlen, Zeichenketten...)
- Sort ist eine abstrakte Klasse (von solchen können
keine Objekte erzeugt werden, sie dienen nur
dazu, hiervon abgeleitete Klassen zu definieren).
113
Praktische Informatik II
7.5.02 - 13
© Stricker/Mattern
Anwendung des Sortierverfahrens
- Es sollen einfache int-Werte sortiert werden, und
zwar unter Benutzung der existierenden generischen
Sortierroutine (ohne diese kennen zu müssen!):
class Int_Sort extends Sort
{ int w;
Dies ist die vom Anwender bereitgestellte
Klasse (der Basisklasse Sort)
Int_Sort(int i) {w = i;}
Konstruktor
boolean kleiner (Sort y)
{ return w < ((Int_Sort)y).w; }
}
Hier wird die Relation "kleiner" definiert und implementiert
class ...
Diese Klasse verwendet beispielhaft Int_Sort
...
Int_Sort[] Tabelle = new Int_Sort[12];
for (int i=0; i<Tabelle.length; i++) {
Tabelle[i] =
Füllen mit Zufallszahlen
new Int_Sort((int)(Math.random()*20.0));
System.out.print(" " + Tabelle[i].w);
} Name einer Klasse,
nicht einer Referenz!
Referenzübergabe!
Int_Sort.sort(Tabelle);
System.out.println();
for (int i=0; i<Tabelle.length; i++)
System.out.print(" " + Tabelle[i].w);
System.out.println();
...
114
Praktische Informatik II
7.5.02 - 14
© Stricker/Mattern
Eine andere Sortieranwendung
class Studi extends Sort {
int Semester; String Name, Fach;
Studi(int S, String F, String N)
Konstruktor
{Semester = S; Name = N; Fach = F;}
Hier darf leider nicht Studi stehen
boolean kleiner (Sort y){
Typkonversion von
Studi s = (Studi) y;
return ((Semester < s.Semester) Sort nach Studi!
|| ((Semester == s.Semester) &&
(Fach.compareTo(s.Fach)<0))
|| ((Semester == s.Semester) &&
(Fach.compareTo(s.Fach)==0) &&
(Name.compareTo(s.Name)<0)));
}
Es wird in erster Linie nach Semesterzahl (absteigend)
}
sortiert, nur bei Gleichheit nach Fach bzw. Name
class ...
...
Studi[] Tab = new Studi[8];
Tab[0] = new Studi(10,"Bio","Hase");
Tab[1] = new Studi(8,"Mathe","Oberzahl");
...
Statt dessen würde man in der Praxis
die Daten von einer Datei einlesen
Tab[7] = new Studi(6,"Physik","Kraft");
Studi, von Sort abgeleitet, kennt auch die Methode sort
Studi.sort(Tab); Es wird ein array vom Typ Sort erwartet,
aber ein array vom Typ Studi übergeben
for (int i=0; i<Tab.length; i++)
System.out.println(Tab[i].Name + " " +
Tab[i].Fach + " " + Tab[i].Semester);
...
115
Praktische Informatik II
7.5.02 - 15
© Stricker/Mattern
Das Sortierergebnis
10 Bio Hase
8 Mathe Oberzahl
8 Mathe Viereck
2 Geologie Steinbeisser
4 Bio Bluemlein
6 E-Technik Strom
10 Mathe Rechenberg
6 Physik Kraft
Rechenberg Mathe 10
Hase Bio 10
Viereck Mathe 8
Oberzahl Mathe 8
Kraft Physik 6
Strom E-Technik 6
Bluemlein Bio 4
Steinbeisser Geologie 2
Die Eingabedaten
Das Sortierergebnis
(absteigend sortiert
entsprechend dem
festgelegten Sortierkriterium "SemesterFach-Name")
- Um eigene Datentypen sortieren zu können, muss die
entsprechende Klasse also nur als abgeleitete Klasse
von "Sort" deklariert werden.
- Ferner muss dort die "kleiner-Operation" geeignet
festgelegt werden.
Praktische Informatik II
7.5.02 - 16
116
© Stricker/Mattern
Sortieren geometrischer Objekte
- Wir sortieren Quadrate und Kreise nach ihrer Fläche
- die Fläche wird jeweils typspezifisch berechnet
abstrakte
Klassen
Sort
kleiner
geo_ob
kleiner
flaeche
Quadrat
Kreis
laenge
radius
flaeche
abstrakt
abstract class geo_ob extends Sort
{ public abstract double flaeche();
boolean kleiner (Sort y)
{ geo_ob x = (geo_ob)y;
return flaeche() < x.flaeche();}
}
class Quadrat extends geo_ob
{ double laenge;
public double flaeche()
{ return (laenge*laenge); };
Quadrat() { laenge = kbdInput.readInt("Laenge? ");}
}
Konstruktor
class Kreis extends geo_ob
{ double radius;
public double flaeche()
{ return (3.14159*radius*radius); };
Kreis() { radius = kbdInput.readInt("Radius? ");}
}
Konstruktor
117
Praktische Informatik II
7.5.02 - 17
© Stricker/Mattern
Das zugehörige Testprogramm
public static void main(String[] args) {
geo_ob[] Tabelle = new geo_ob[3];
for (int i=0; i<Tabelle.length; i++) {
String s = kbdInput.readString
("Kreis (k) oder Quadrat (q) ? ");
if (s.compareTo("k") == 0)
Polymorphie
Tabelle[i] = new Kreis();
else Tabelle[i] = new Quadrat();
}
geo_ob.sort(Tabelle); System.out.println();
for (int i=0; i<Tabelle.length; i++)
System.out.print(" " + Tabelle[i].flaeche() );
System.out.println();
}
Hier wird jeweils
die "richtige"
Methode für die
Fläche verwendet
Kreis (k) oder Quadrat (q) ? k
Radius? 5
Kreis (k) oder Quadrat (q) ? q
Laenge? 3
Kreis (k) oder Quadrat (q) ? q
Laenge? 7
78.5397
49
9
118
Praktische Informatik II
7.5.02 - 18
© Stricker/Mattern
Java: Mehrfachvererbung?
- Zweck: "mix in"; Verheiraten mehrerer Konzepte
- Beispiel: geometrische Formen
geometrisches verschiebe()
Objekt
fläche()
umfang()
färbe()
gefülltes
Objekt
Quadrat
versende()
empfange()
über Internet
verschickbar
gefülltes
Quadrat
- "gefülltes" Quadrat soll Methoden und Attribute von mehreren
Klassen erben können
- keine Baumstruktur, sondern gerichteter Graph!
- Probleme:
- gleich benannte Attribute in verschiedenen Vorgängerklassen:
welches davon wird geerbt?
- oft nicht zu vermeiden, da Vorgängerklassen von verschiedenen
Entwicklern realisiert wurden
- daher Mechanismen zur "Konfliktauflösung" notwendig (z.B. beim
Erben umbenennen; Angabe, welche man erben möchte; Sprachregeln, die festlegen, was im Konfliktfall Vorrang hat etc.)
- Mehrfachvererbung z.B. möglich in C++, aber nicht
in Java
- um Sprache (und Implementierung) einfach zu halten
- als teilweisen Ersatz dafür dienen in Java die "Interfaces"
119
Praktische Informatik II
7.5.02 - 19
© Stricker/Mattern
Schnittstellen ("Interfaces")
- Interface = (abstrakte) Klasse, die alle Methoden
nur deklariert, aber nicht implementiert
- enthält also nur (implizit) abstrakte Methoden (und Konstanten)
- Bsp: interface Menge {
int cardinal();
void insert (Object x);
statt
void remove (Object x);
"class"
}
Oberklasse
aller Objekte
- alle "Variablen" sind automatisch public static final (also Konstanten)
- alle Methoden sind automatisch public abstract
- Interface muss von anderen Klassen implementiert werden
- Bsp: class S implements Menge {
...
public int cardinal(); {
...
while ... i++ ...
return i;
}
- implements hat die gleiche Rolle wie extends bei "echten" Klassen
- es kann auch eine entsprechende Hierarchie entstehen
- Der Typ des Interfaces (hier: "Menge") kann mit
seinen Methoden anderswo benutzt werden
- Bsp: Menge M;
M.insert(...);
120
Praktische Informatik II
7.5.02 - 20
© Stricker/Mattern
Mehrfacherweiterungen
- Interfaces können mehrere andere erweitern
- Bsp: interface A {...}
interface B {...}
interface I extends A, B {...}
int X();
}
- I "enthält" alle Methoden von A und B (und zusätzlich X)
- eine Klasse dagegen kann nur eine einzige Klasse erweitern (aber
gleichzeitig mehrere Interfaces implementieren):
class P extends Q implements A,B,... {...}
- Das sogen. "diamond inheritance problem" ist so entschärft:
W
X
Y
interface W {...}
interface X extends W {...}
class Y implements W {...}
class Z extends Y implements X {...}
Z
- die von Z ererbten Attribute und Methodenimplementierungen
können nur aus Y (und nicht indirekt doppelt aus W stammen)
121
Praktische Informatik II
7.5.02 - 21
© Stricker/Mattern
Schnittstellen ("Interfaces")
- Interface = (abstrakte) Klasse, die alle Methoden
nur deklariert, aber nicht implementiert
- enthält also nur (implizit) abstrakte Methoden (und Konstanten)
- Bsp: interface Menge {
int cardinal();
void insert (Object x);
statt
void remove (Object x);
"class"
}
Oberklasse
aller Objekte
- alle "Variablen" sind automatisch public static final (also Konstanten)
- alle Methoden sind automatisch public abstract
- Interface muss von anderen Klassen implementiert werden
- Bsp: class S implements Menge {
...
public int cardinal(); {
...
while ... i++ ...
return i;
}
- implements hat die gleiche Rolle wie extends bei "echten" Klassen
- es kann auch eine entsprechende Hierarchie entstehen
- Der Typ des Interfaces (hier: "Menge") kann mit
seinen Methoden anderswo benutzt werden
- Bsp: Menge M;
M.insert(...);
120
Praktische Informatik II
7.5.02 - 22
© Stricker/Mattern
Ausnahmen (Exceptions)
- Ausnahmen sind Fehlerereignisse
- werden oft vom System ausgelöst ("throw")
- können aber auch explizit im Programm ausgelöst werden
- können abgefangen und behandelt werden ("catch")
- Bessere Strukturierung durch "try" und "catch":
readFile() {
try {
// open the file;
// determine its size;
// allocate that much memory;
// read the file into memory;
// close the file;
} catch (fileOpenFailed) {
// doSomething;
} catch (sizeDeterminationFailed) {
// doSomething;
} catch (memoryAllocationFailed) {
// doSomething;
} catch (readFailed) {
// doSomething;
} catch (fileCloseFailed) {
// doSomething;
}
}
- Fehlerbehandlung muss auf diese Weise nicht mit dem "normalen"
Programmcode verwoben werden
Praktische Informatik II
7.5.02 - 23
© Stricker/Mattern
Ausnahmen - ein E/A-Beispiel
import java.io.*;
Da wir Fehler selbst
public class EA_Beispiel
abfangen, können
// Prints "Hello World" to a file
wir auf "throws..."
// specified by the first parameter. verzichten!
{
public static void main(String args[])
{
FileOutputStream out = null;
// Attempt to open the file, if we
// can't display error and quit
try
{
out = new FileOutputStream(args[0]);
}
Diese Fehlerklasse ganz
oben in der Hierarchie und
catch (Throwable e)
fängt damit alles ab
{
System.out.println("Error in opening file");
System.exit(1);
}
Z.B.: Zugriffsrechte "falsch"
PrintStream ps = new PrintStream(out);
try
{
}
Fehler hierbei würden nicht abgefangen!
ps.println("Hello World");
out.close();
Über diese Variable kann man
}
catch(IOException e) mehr über den Fehler erfahren
{
System.out.println("I/O Error");
System.exit(1);
}
}
Shortcut zum Verlassen des Programms
Praktische Informatik II
7.5.02 - 24
© Stricker/Mattern
Fehlerarten
- Typische Situationen, in denen Ausnahmen
auftreten können:
- Ein- / Ausgabe (IOException)
- Netz (z.B. MalformedURLException)
- Erzeugen von Objekten mit "new"
- Typkonvertierung (z.B. NumberFormatException)
- Wichtige Fehlerklasse: Laufzeitfehler
- können, müssen aber nicht abgefangen werden
- Beispiele: Zugriff über Null-Referenz; int / 0; Indexfehler bei arrays
try {
value = value / x;
}
catch(ArithmeticException e){
System.out.println("Division durch 0?");
}
- Alle anderen Fehlerarten müssen behandelt werden
- entweder durch try / catch in der Methode
- oder durch Angabe, dass die Methode diese Ausnahme selbst
wieder auslöst (und damit weiterreicht), z.B.:
import java.io.*;
public Eine_Methode (...)
throws java.io.IOException
{... read ...}
Praktische Informatik II
7.5.02 - 25
© Stricker/Mattern
Praktische Informatik II
7.5.02 - 26
© Stricker/Mattern
Praktische Informatik II
7.5.02 - 27
© Stricker/Mattern
Praktische Informatik II
7.5.02 - 28
© Stricker/Mattern
Herunterladen