Friedrich-Alexander-Universität Erlangen-Nürnberg

Werbung
Algorithmik 1
M. Phillipsen, H. Stoyan, M. Stamminger
Friedrich-Alexander-Universität
Erlangen-Nürnberg
Informatik 2/8/9
Kapitel 7 - Java-Details
7.1
7.2
7.3
7.4
7.5
Codier-Regeln für Java
Vererbung am Beispiel
Graphische Oberfläche
Unter der Lupe
Was geht schief?
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-2
M. Stamminger
7.1 Codier-Regeln für Java
ƒ Wenn Sie wirklich wollen, dann könnten Sie ihre Programme schreiben,
ohne jemals die Return-Taste zu drücken.
ƒ Die Anordnung in Zeilen ist nur für den menschlichen Leser.
ƒ Ebenso ist das Einrücken aus Sicht der Übersetzers völlig unnötig. Es dient
lediglich dem besseren Verständnis, weil man auf einen Blick erkennt, wo
z.B. eine Schleife beendet ist.
Æ Derartige Regeln heißen Codier-Regeln.
In diesem Abschnitt besprechen wir übliche Codier-Regeln für Java.
Bitte einhalten!
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-3
M. Stamminger
7.1 Codier-Regeln für Java
Mehr Motivation
ƒ Im Durchschnitt fallen 80% der Kosten eines Programms während der
Wartung an.
ƒ Kaum ein Programm wird über seine ganze Lebensdauer vom
ursprünglichen Autor betreut.
ƒ Codier-Regeln verbessern die Lesbarkeit von Software; neuer Code ist
leichter zu begreifen; die Kosten der Wartung werden gesenkt.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-4
M. Stamminger
7.1 Codier-Regeln für Java
Codier-Regeln für Dateinamen
ƒ Quellcode-Dateien haben den Suffix .java
ƒ ByteCode-Dateien haben den Suffix .class
ƒ Maximal eine öffentliche Klasse pro Quelldatei. Ist eine öffentliche Klasse
namens X im Quellcode, dann muss die Quellcode-Datei X.java heißen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-5
M. Stamminger
7.1 Codier-Regeln für Java
Codier-Regeln für Programmdateien
ƒ Mehr als 2.000 Zeilen sollte keine Programmdatei lang sein
ƒ Leerzeilen zur optischen Trennung
ƒ Generelle Struktur jeder Programmdatei
1. Anfangskommentar
/*
/*
** Klassenname
Klassenname
**
** Versionsangabe
Versionsangabe
**
** Datum
Datum
**
** Copyright-Angabe,
Copyright-Angabe, Autoren
Autoren
*/
*/
2. package und import-Anweisung
3. class und interface Deklarationen
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-6
M. Stamminger
7.1 Codier-Regeln für Java
Codier-Regeln für class und interface Deklarationen
ƒ Generelle Struktur jeder class und interface Deklaration
1. externer Kommentar /** … */
2. class … { oder interface … {
3. interner Kommentar
4. statische Variablen
in der Reihenfolge public, protected, (package), private
5. Instanzvariablen
in der Reihenfolge public, protected, (package), private
6. Konstruktoren
7. Methoden
nach Funktionalität gruppiert
unabhängig von der Sichtbarkeit
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-7
M. Stamminger
7.1 Codier-Regeln für Java
Programmzeilenformatierung (1)
ƒ Einrückungen sollten in 4er-Schritten erfolgen
ƒ Keine Zeile sollten mehr als 80 Zeichen enthalten,
Kommentarzeilen nicht mehr als 70 Zeichen
ƒ Wenn die Zeile zu lang wird, möglichst an folgenden Stellen umbrechen:
y nach einem Komma
int a,| b
y vor einem Operator
47 |+ 11
y möglichst gemäß der Bindungsstärke
ƒ Die Folgezeile wird so weit eingerückt wie der Ausdruck „auf gleicher
Schachtelungsebene“ in der vorhergehenden Zeile.
ƒ Wenn dabei zu tief eingerückt würde, dann einen 8er-Schritt gegenüber der
vorherigen Zeile einrücken.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-8
M. Stamminger
7.1 Codier-Regeln für Java
Programmzeilenformatierung (2)
someMethod1(longExpression1,
someMethod1(longExpression1, longExpression2,
longExpression2, longExpression3,
longExpression3,
longExpression4);
longExpression4);
var
var == someMethod(longExpression1,
someMethod(longExpression1,
someMethod2(longExpression2,
someMethod2(longExpression2,
longExpression3));
longExpression3));
longName1
longName1 == longName2
longName2 ** (longName3
(longName3 ++ longName4
longName4 -- longName5)
longName5)
++ 44 ** longName6;
longName6;
//obige
//obige Formatierung
Formatierung ist
ist besser
besser als:
als:
longName1
longName1 == longName2
longName2 ** (longName3
(longName3 ++ longName4
longName4
-- longName5)
longName5) ++ 44 ** longName6;
longName6;
Leerzeichen zwischen Operator und Operanden
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-9
M. Stamminger
7.1 Codier-Regeln für Java
Programmzeilenformatierung (3)
//übliche
//übliche Formatierung:
Formatierung:
someMethod(int
someMethod(int anArg,
anArg, Object
Object anotherArg,
anotherArg, String
String yetAnotherArg,
yetAnotherArg,
Object
Object andStillAnother)
andStillAnother) {{
...
...
}}
//wenn
//wenn zu
zu tief
tief eingrückt
eingrückt werden
werden würde
würde
private
private static
static synchronized
synchronized veryLongMethodName(int
veryLongMethodName(int anArg,
anArg,
Object
Object anotherArg,
anotherArg, String
String yetAnotherArg,
yetAnotherArg,
Object
Object andStillAnotherArg)
andStillAnotherArg) {{
...
...
}}
mit „normaler“ Einrückregel,
würde es in Folgezeile hier
weitergehen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-10
M. Stamminger
7.1 Codier-Regeln für Java
Programmzeilenformatierung (4)
ƒ Werden Bedingungen von if-Anweisungen zu lang, stets
mindestens 8 Schritte einrücken
//schlechte
//schlechte Formatierung:
Formatierung:
if
if ((condition1
((condition1 &&
&& condition2)
condition2)
||
|| (condition3
(condition3 &&
&& condition4)
condition4)
||!(condition5
||!(condition5 &&
&& condition6))
condition6)) {{
doSomethingAboutIt();
doSomethingAboutIt();
}}
//Verwenden
//Verwenden Drucker
Drucker o.
o.
//Terminal
//Terminal falsche
falsche
//Zeilenlänge,
//Zeilenlänge, dann
dann ist
ist
//Rumpf
//Rumpf leicht
leicht zu
zu
//übersehen!
//übersehen!
//besser:
//besser:
if
if ((condition1
((condition1 &&
&& condition2)
condition2)
||
|| (condition3
(condition3 &&
&& condition4)
condition4)
||!(condition5
||!(condition5 &&
&& condition6))
condition6)) {{
doSomethingAboutIt();
doSomethingAboutIt();
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-11
M. Stamminger
7.1 Codier-Regeln für Java
Programmzeilenformatierung (5)
Bedingung wahr? dann
ƒ Formatierung des Fragezeichen-Operators:erster Ausdruck : sonst
zweiter Ausdruck.
Bedingung in Klammern
//je
//je nach
nach Geschmack:
Geschmack:
alpha
alpha == (aLongBooleanExpression)
(aLongBooleanExpression) ?? (int)
(int) beta
beta :: gamma++;
gamma++;
alpha
alpha == (aLongBooleanExpression)
(aLongBooleanExpression) ?? (int)
(int) beta
beta
:: gamma++;
gamma++;
alpha
alpha == (aLongBooleanExpression)
(aLongBooleanExpression)
?? (int)
(int) beta
beta
:: gamma++;
gamma++;
Leerzeichen nach expliziter Typwandlung
Nie Leerzeichen bei unären Operatoren
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-12
M. Stamminger
7.1 Codier-Regeln für Java
Kommentare
ƒ In Java unterscheidet man zwischen Kommentaren zur Implementierung
und Kommentaren zur Dokumentation.
y Implementierungskommentare werden mit // oder /*…*/ geschrieben.
à Beschreiben Implementierungsgedanken
à Vor-/Nachbedingungen, Invarianten
à Auskommentieren von Code, der nicht mehr gebraucht wird
y Dokumentationskommentare werden durch /**…*/ gekennzeichnet.
à Beschreibung für Entwickler, die die Klasse benutzen wollen.
à Funktionsweise, Bedeutung der Argumente von Methoden, …
y Das Werkzeug javadoc kann Dokumentationskommentare extrahieren und
html-Seiten generieren, wie Sie diese aus der Dokumentation der StandardBibliotheken kennen.
ƒ Redundante Kommentare vermeiden
ƒ Daumenregel: Wenn ein Programmstück so trickreich ist, dass man als
Programmierer einen Implementierungskommentar als unbedingt notwendig
betrachtet, dann besser den Code klarer schreiben!
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-13
M. Stamminger
7.1 Codier-Regeln für Java
Dokumentationskommentar am Beispiel (1)
/**
/**
** Returns
Returns an
an Image
Image object
object that
that can
can then
then be
be painted
painted
** on
on the
the screen.
screen.
** <p>
<p>
** The
The name
name argument
argument is
is aa specifier
specifier that
that ……
**
** @param
@param url
url an
an absolute
absolute URL
URL giving
giving the
the base
base location
location
**
name
name the
the location
location of
of the
the image,
image, relative
relative to
to url
url
** @return
the
image
at
the
specified
URL
@return the image at the specified URL
** @see
Image
@see
Image
*/
*/
public
public Image
Image getImage(URL
getImage(URL url,
url, String
String name)
name) {{
try
try {{
return
return getImage(new
getImage(new URL(url,
URL(url, name));
name));
}} catch
catch (MalformedURLException
(MalformedURLException e)
e) {{
return
return null;
null;
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-14
M. Stamminger
7.1 Codier-Regeln für Java
Dokumentationskommentar am Beispiel (2)
getImage
getImage
public
public Image
Image getImage(URL
getImage(URL url,
url,
String
String name)
name)
Returns
Returnsan
anImage
Imageobject
objectthat
thatcan
canthen
thenbe
bepainted
paintedon
onthe
thescreen.
screen.
The
Theargument
argumentisisaaspecifier
specifierthat
that…
…
Parameters:
Parameters:
url
url--an
anabsolute
absoluteURL
URLgiving
givingthe
thebase
baselocation
location
name
name--the
thelocation
locationofofthe
theimage,
image,relative
relativetotourl
url
Returns:
Returns:
the
theimage
imageatatthe
thespecified
specifiedURL
URL
See
SeeAlso:
Also:
Image
Image
Mehr Informationen unter: http://java.sun.com/j2se/javadoc/
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-15
M. Stamminger
7.1 Codier-Regeln für Java
Deklarationen (1)
ƒ Eine Deklaration pro Zeile, vermeide Komma-Form (int a,b;)
ƒ Initialisierung möglichst unmittelbar an der Deklarationsstelle
ƒ Deklarationen am Anfang eines Blocks {…}, also nicht warten, bis die
Variable benötigt wird. Nur Laufvariablen von for-Schleifen werden nicht an
den Anfang des umgebenden Blocks gezogen.
ƒ In der Klassendeklaration Leerzeichen vor {
Beispiel: class Sample extends Object {
ƒ Leerzeichen bei Methodendeklaration gemäß
foo(int i, int j) {
ƒ } immer in einer eigenen Zeile, so weit eingerückt wie Eröffnung.
ƒ Leerzeile zwischen 2 Methodendeklarationen
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-16
M. Stamminger
7.1 Codier-Regeln für Java
Deklarationen (2)
Leerzeichen
ohne Leerzeichen
class
class Sample
Sample extende
extende Object
Object {{
int
int ivar;
ivar;
int
int ivar2;
ivar2;
Sample(int
Sample(int i,
i, int
int j)
j) {{
ivar
ivar == i;
i;
ivar
ivar == j;
j;
}}
int
int emptyMethod()
emptyMethod() {}
{}
...
...
}}
} in eigener Zeile,
eingerückt wie class
Leerzeichen
Leerzeile
} in eigener Zeile,
eingerückt wie Sample
Leerzeile
ausnahmesweise } in
gleicher Zeile
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-17
M. Stamminger
7.1 Codier-Regeln für Java
Anweisungen (1)
ƒ Nur eine Anweisung pro Zeile
ƒ { steht am Ende der Zeile derjenigen Anweisung, die Block öffnet
ƒ return: Rückgabewert
if
if (condition)
(condition) {{
nicht in Klammern ()
statements;
statements;
ƒ if-Anweisungen:
}}
Stets {} verwenden, auch
if
if (condition)
(condition) {{
statements;
wenn nur eine Anweisung
statements;
}} else
in einem Zweig ist.
else {{
statements;
statements;
}}
if
if (condition)
(condition) {{
statements;
statements;
}} else
else if
if (condition)
(condition) {{
statements;
statements;
}} else
else {{
statements;
statements;
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-18
M. Stamminger
7.1 Codier-Regeln für Java
Anweisungen (2)
ƒ Schleifen:
Nicht mehr als 3 Variablen
gleichzeitig verändern.
for
for (initialization;
(initialization; condition;
condition; update)
update) {{
statements;
statements;
}}
Leerzeichen
//leere
//leere Schleife:
Schleife:
for
for (initialization;
(initialization; condition;
condition; update);
update);
while
while (condition)
(condition) {{
statements;
statements;
}}
do
do {{
statements;
statements;
}} while
while (condition);
(condition);
Leerzeichen zwischen Schlüsselwort und (
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-19
M. Stamminger
7.1 Codier-Regeln für Java
Anweisungen (3)
ƒ switch-Anweisung:
switch
switch (condition)
(condition) {{
case
case ABC:
ABC:
statements;
statements;
/*
/* fällt
fällt durch
durch */
*/
case
DEF:
case DEF:
statements;
statements;
break;
break;
case
case XYZ:
XYZ:
statements;
statements;
break;
break;
default:
default:
statements;
statements;
break;
break;
}}
Kommentar, wenn wirklich
„Durchrauschen“ in den
nächsten Fall beabsichtigt
ist. Dann keine Leerzeile.
Leerzeile zwischen
zwei Fällen.
default-Fall
immer vorsehen.
Redundantes break
schützt bei nachträglich
ergänzten neuen Fällen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-20
M. Stamminger
7.1 Codier-Regeln für Java
Anweisungen (4)
ƒ try-Anweisung:
try
try {{
statements;
statements;
}} catch
catch (ExceptionClass
(ExceptionClass e)
e) {{
statements;
statements;
}} finally
finally {{
statements;
statements;
}}
ggf. ohne finally.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-21
M. Stamminger
7.1 Codier-Regeln für Java
Namensgebung (1)
ƒ Alle Namen sollten so gewählt werden, dass sie schon beim Lesen erklären,
was sie bedeuten und welche Funktion sie im Programm haben. Solche
Namen heißen mnemonische Namen.
y Keine winzigen, erst recht keine einbuchstabigen Namen verwenden
y Ausnahmen:
à Laufvariablen von Schleifen (typisch: i, j, k)
à temporäre „Wegwerf“-Variablen, die nur an einer Stelle benutzt werden, z.B. um die
Werte zweier Variable zu vertauschen.
ƒ Paketnamen sollten nur aus Kleinbuchstaben bestehen. Dabei nimmt man
üblicherwiese „seine“ Domain rückwärts als Präfix:
Beispiel: de.uni-erlangen.informatik.i9.algo1
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-22
M. Stamminger
7.1 Codier-Regeln für Java
Namensgebung (2)
ƒ Klassennamen und Schnittstellennamen sollten Substantive sein und mit
einem Großbuchstaben beginnen. Bei zusammengesetzten Substantiven
beginnt jedes neue Wort wieder mit einem Großbuchstaben.
Beispiele: class Rational, class BibliotheksBenutzer
ƒ Methodennamen sind Verben und beginnen mit einem Kleinbuchstaben. Bei
zusammengesetzten Verben beginnt jedes neue Wort mit einem
Großbuchstaben.
Beispiele: run(), runFast()
ƒ Variablennamen fangen mit Kleinbuchstaben an (weder _ noch $). Bei
zusammengesetzten Substantiven beginnt jedes neue Wort wieder mit
einem Großbuchstaben.
ƒ Namen konstanter Werte nutzen ausschließlich Großbuchstaben.
Bei Zusammensetzung _ zur Worttrennung verwenden.
Beispiele: MIN_WIDTH, MAX_LENGTH
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-23
M. Stamminger
7.1 Codier-Regeln für Java
Code-Klarheit (1)
ƒ Instanzvariablen sollten nur mit wirklich gutem Grund öffentlich zugänglich
sein. Lieber set() und get() Methoden verwenden, die den Wert der
Instanzvariablen setzen bzw. zurückliefern.
ƒ Niemals ein Objekt verwenden, um (statische) Klassenvariablen oder
(statische) Klassenmethode aufzurufen. Lieber Klassenname.name
ƒ Keine Kettenzuweisungen machen: a = b = c;
ƒ Keine Zuweisung verwenden, wo sie mit einer Vergleichsoperation
verwechselt werden kann:
if (a = d) { …
Lieber: if ((a = d) == true) { …
ƒ Auf eingebettete Zuweisungen verzichten
d = (a = b + c) + r
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-24
M. Stamminger
7.1 Codier-Regeln für Java
Code-Klarheit (2)
ƒ Konstante Werte sollten (fast) nie explizit als Literale im Code stehen.
Stattdessen Konstante mit Namen deklarieren und den Namen im Code
nutzen.
ƒ Im Zweifel zu viel Klammern
if (a == b && c == d)
Lieber:
if ((a == b) && (c == d))
Nicht jedem Leser des Programms sind die Präzedenzregeln klar.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-25
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbeispiel (1)
Kugel
Festkörper
Quader
Zylinder
mit abstrakter Klasse:
public
public abstract
abstract class
class Festkoerper
Festkoerper {{
public
public final
final static
static float
float PI
PI == 3.1415926;
3.1415926;
public
public abstract
abstract double
double oberflaeche();
oberflaeche();
public
abstract
double
volumen();
public abstract double volumen();
}}
oder mit Interface:
public
public interface
interface Festkoerper
Festkoerper {{
public
public final
final static
static float
float PI
PI == 3.1415926;
3.1415926;
public
public double
double oberflaeche();
oberflaeche();
public
public double
double volumen();
volumen();
}}
Beides ist
sinnvoll, weil
die Klasse nur
abstrakte
Methoden und
Konstanten
deklariert.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-26
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbsp. (2)
Zustand Oberfläche
Quader
ƒ Quader:
Länge,
Breite,
Höhe
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
Volumen
Länge·Breite·Höhe
Zylinder Radius,
Höhe
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
Kugel
4·π·Radius²
Radius
4/3·π·Radius3
public
public class
class Quader
Quader implements
implements Festkoerper
Festkoerper {{
private
private double
double laenge,
laenge, breite,
breite, hoehe;
hoehe;
public
public double
double oberflaeche()
oberflaeche() {{
return
return 22 ** (laenge
(laenge ** breite
breite ++ laenge
laenge ** hoehe
hoehe
++ breite
breite ** hoehe);
hoehe);
}}
public
public double
double volumen()
volumen() {{
return
return laenge
laenge ** breite
breite ** hoehe;
hoehe;
}}
...}
...}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-27
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbsp. (3)
Zustand Oberfläche
Quader
Länge,
Breite,
Höhe
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
Volumen
Länge·Breite·Höhe
Zylinder Radius,
Höhe
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
Kugel
4·π·Radius²
Radius
4/3·π·Radius3
ƒ Zylinder:
public
public class
class Zylinder
Zylinder implements
implements Festkoerper
Festkoerper {{
private
private double
double radius,
radius, hoehe;
hoehe;
public
public double
double volumen()
volumen() {{
return
return PI
PI ** radius
radius ** radius
radius ** hoehe;
hoehe;
}}
public
public double
double oberflaeche()
oberflaeche() {{
return
return 22 ** PI
PI ** radius
radius ** (radius
(radius ++ hoehe);
hoehe);
}}
...}
...}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-28
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbsp. (4)
Zustand Oberfläche
Quader
Länge,
Breite,
Höhe
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
Volumen
Länge·Breite·Höhe
Zylinder Radius,
Höhe
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
Kugel
4·π·Radius²
Radius
4/3·π·Radius3
ƒ Kugel:
public
public class
class Kugel
Kugel implements
implements Festkoerper
Festkoerper {{
private
private double
double radius;
radius;
public
public double
double volumen()
volumen() {{
return
return 4.0/3.0
4.0/3.0 ** PI
PI ** radius
radius ** radius
radius ** radius;
radius;
}}
public
public double
double oberflaeche()
oberflaeche() {{
return
return 44 ** PI
PI ** radius
radius ** radius;
radius;
}}
...}
...}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-29
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbeispiel (5)
Festkoerper
Festkoerper ff == new
new Kugel();
Kugel();
System.out.println(f.volumen());
System.out.println(f.volumen());
ff == new
new Zylinder();
Zylinder();
System.out.println(f.volumen());
System.out.println(f.volumen());
Abhängig vom dynamischen
Typ des Objekts (von welchem
Typ ist f zur Laufzeit?) wird
die zugehörige konkrete
Implementierung aufgerufen.
Variable vom Typ einer
Schnittstelle (oder einer
abstrakten Klasse). Jede
Instanz muss die
Methoden der Schnittstelle
implementieren.
bei statischen
Methoden und
Instanzvariablen
gelten andere
Regeln
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-30
M. Stamminger
7.2 Vererbung am Beispiel
Mehrfachvererbung
eingeschränkt auch
in Java
interface
interface BaseColors
BaseColors {{
int
int RED
RED == 1;
1;
int
int GREEN
GREEN == 2;
2;
int
int BLUE
BLUE == 4;
4;
}}
interface
interface RainbowColors
RainbowColors
extends
extends BaseColors
BaseColors {{
int
int YELLOW
YELLOW == 3;
3;
int
int ORANGE
ORANGE == 5;
5;
int
INDIGO
=
6;
int INDIGO = 6;
int
int VIOLET
VIOLET == 7;
7;
}}
interface
interface PrintColors
PrintColors
extends
extends BaseColors
BaseColors {{
int
int YELLOW
YELLOW == 8;
8;
int
== 16;
int CYAN
CYAN
16;
int
int MAGENTA
MAGENTA == 32;
32;
}}
interface
interface LotsOfColors
LotsOfColors
extends
extends RainbowColors,
RainbowColors,
PrintColors
PrintColors {{
int
int FUCHSIA
FUCHSIA == 17;
17; ……
}}
OK, solange nicht auf
YELLOW zugegriffen wird.
Fehler auch wenn jeder
Pfad YELLOW auf den
selben Wert setzen würde
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-31
M. Stamminger
7.2 Vererbung am Beispiel
Festkörperbeispiel (6)
public
public class
class Kugel
Kugel implements
implements Festkoerper,
Festkoerper, LotsOfColors
LotsOfColors {{
...
...
int
int color
color == RED;
RED; //alles
//alles ok
ok
Kugel(int
Kugel(int color)
color) {{
if
if ((color
((color << MIN_COLOR)
MIN_COLOR) ||
|| (color
(color >> MAX_COLOR))
MAX_COLOR)) {{
this.color
this.color == YELLOW;
YELLOW; //Fehler
//Fehler zur
zur Übersetzungszeit
Übersetzungszeit
}} else
else {{
this.color
this.color == color;
color;
}}
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-32
M. Stamminger
7.3 Graphische Oberfläche
ƒ SWING erlaubt das Gestalten von graphischen Benutzeroberflächen mit
Knöpfen, Menüs, Schiebereglern usw. in einer plattformunabhängigen
Weise für MS Windows/NT, MacOS, Solaris, Linux, u.a.
ƒ Das Erscheinungsbild wird an die jeweilige Plattform angepasst.
ƒ Wir benutzen die Komponenten aus der SWING-Bibliothek (z. B. JButton),
nicht die Komponenten aus der AWT-Bibliothek (also nicht Button),
müssen aber auch auf Klassen in der AWT- Bibliothek (z. B.
GridBagLayout) zurückgreifen.
ƒ Plan für das Lernen der Grundkonzepte:
y Welche einfachen graphischen Interaktionskomponenten gibt es?
y Wie werden sie auf dem Bildschirm angezeigt und angeordnet?
y Wie reagieren sie auf Eingaben und Benutzung?
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-33
M. Stamminger
Interaktionskomponenten (1)
7.3 Graphische Oberfläche
JButton
Knopf, Schaltfläche
JCheckBox Ankreuzfeld
JFrame
Rahmen mit Titelbalken etc.
JLabel
Beschriftung
JList
Auswahlliste
JPanel
Behälter zum Gruppieren und
Anordnen v. Komponenten
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-34
M. Stamminger
Interaktionskomponenten (2)
7.3 Graphische Oberfläche
JRadioButton Umschaltknopf
ButtonGroup
Mehrere
Knöpfe, von
denen nur
einer gedrückt
ist
JScrollbar
Verschiebebalken
JSlider
Schieberegler
JTextField
JTextArea
Editierbares
einzeiliges
bzw.
mehrzeiliges
Textfeld
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-35
M. Stamminger
7.3 Graphische Oberfläche
Gedanklicher Aufbau eines Fensters:
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-36
M. Stamminger
7.3 Graphische Oberfläche
Aufbau eines Fensters in der Datenstruktur:
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-37
M. Stamminger
7.3 Graphische Oberfläche
Das erste Swing-Programm (1)
import
import java.awt.*;
java.awt.*;
import
import java.awt.event.*;
java.awt.event.*;
import
import javax.swing.*;
javax.swing.*;
public
public class
class RahmenMitKnopf
RahmenMitKnopf {{
public
public static
static void
void main
main (String
(String args[])
args[]) {{
JFrame
JFrame rr == new
new JFrame("RahmenMitKnopf");
JFrame("RahmenMitKnopf");
Komponenten, die später in den Rahmen eingefügt werden, werden
i.A. zeilenweise von links nach rechts im Fenster angeordnet.
Rahmengröße richtet sich nach Größe der Komponenten
JButton
JButton kk == new
new JButton("Knoepfle");
JButton("Knoepfle");
k.SetToolTipText("tut
k.SetToolTipText("tut nichts");
nichts"); //Hinweistext
//Hinweistext
r.getContentPane().add(k);
r.getContentPane().add(k);
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-38
M. Stamminger
7.3 Graphische Benutzeroberfläche
Das erste Swing-Programm (2)
ƒ Funktionalität wird in Objekten gekapselt
Hier: beim Schließen des Fensters soll sich das Programm
beenden
class
class MyCloser
MyCloser extends
extends WindowAdapter
WindowAdapter {{
public
public void
void windowClosing(WindowEvent
windowClosing(WindowEvent e)
e) {{
System.exit(0);
System.exit(0);
}}
}}
Separate Klassendefinition für jedes mögliche Ereignis
ist lästig. "Anonyme innere Klassen" helfen, s.u.
...
...
JFrame
JFrame rr == new
new JFrame("RahmenMitKnopf");
JFrame("RahmenMitKnopf");
r.addWindowListener(new
r.addWindowListener(new MyCloser());
MyCloser());
...
...
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-39
Wenn der Rahmen
das Ereignis
windowClosing
sieht, dann wird die
entspr. Methode des
Objekts myCloser
aufgerufen.
M. Stamminger
Das erste Swing-Programm (3)
7.3 Graphische Oberfläche
import
import java.awt.*;
java.awt.*;
import
import java.awt.event.*;
java.awt.event.*;
import
import javax.swing.*;
javax.swing.*;
public
public class
class RahmenMitKnopf
RahmenMitKnopf {{
public
public static
static void
void main
main (String
(String args[])
args[]) {{
JFrame
JFrame rr == new
new JFrame("RahmenMitKnopf");
JFrame("RahmenMitKnopf");
r.addWindowListener(new
r.addWindowListener(new WindowAdapter()
WindowAdapter() {{
public
public void
void windowClosing(WindowEvent
windowClosing(WindowEvent e)
e) {{
System.exit(0);
System.exit(0);
}}
});
//Anonyme
});
//Anonyme Innere
Innere Klasse!
Klasse!
JButton
JButton kk == new
new JButton("Knoepfle");
JButton("Knoepfle");
k.setToolTipText("tut
k.setToolTipText("tut nichts");
nichts"); //Hinweistext
//Hinweistext
r.getContentPane().add(k);
r.getContentPane().add(k);
r.pack();
r.pack();
r.setVisible(true);
r.setVisible(true);
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-40
M. Stamminger
7.3 Graphische Oberfläche
ƒ Die Lage der Komponenten im Fenster wird nur relativ spezifiziert. Ändert
sich die Größe des Fensters, wird diese Größenänderung an alle
Komponenten des Fensters weitergegeben.
ƒ Bisher: Fließplatzierer („FlowLayout“): Komponenten werden
nacheinander von links nach rechts im Fenster angezeigt.
add(e), add(e,i), remove(e), remove(i), removeAll()…
ƒ Weitere Platzierer:
y
y
y
y
Gitteranordnung (2D-Raster):
Einfassungsanordnung:
Schachtelanordnung:
Variable Rasteranordnung:
GridLayout
BorderLayout
BoxLayout
GridBagLayout
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-41
M. Stamminger
7.3 Graphische Oberfläche
Gitteranordnung, GridLayout (1)
ƒ Einer der Konstruktoren: GridLayout(int zeilen, int spalten)
Dieser legt ein Gitter mit der angegebenen Zeilen-/Spaltenzahl an.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-42
M. Stamminger
7.3 Graphische Oberfläche
Gitteranordnung, GridLayout (2)
import
import java.awt.*;
java.awt.*;
import
import java.awt.event.*;
java.awt.event.*;
import
import javax.swing.*;
javax.swing.*;
class
class Gitteranordnung{
Gitteranordnung{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
JFrame
JFrame rr == new
new JFrame("Gitter
JFrame("Gitter -- Anordnung");
Anordnung");
JPanel
JPanel pp == new
new JPanel(new
JPanel(new GridLayout(2,3));
GridLayout(2,3));
p.add(new
p.add(new JButton("Knopf1"));
JButton("Knopf1"));
p.add(new
p.add(new JButton("Knopf2"));
JButton("Knopf2"));
p.add(new
p.add(new JButton("3"));
JButton("3"));
p.add(new
p.add(new JButton("Knopf
JButton("Knopf mit
mit langem
langem Text"));
Text"));
p.add(new
p.add(new JButton("Knopf5"));
JButton("Knopf5"));
r.getContentPane().add(p);
r.getContentPane().add(p);
r.pack();
r.pack();
r.setVisible(true);
r.setVisible(true);
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-43
M. Stamminger
7.3 Graphische Oberfläche
Einfassungsanordnung, BorderLayout (1)
ƒ maximal 5 Komponenten werden angeordnet: in der Mitte und in jeder der
vier Himmelsrichtungen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-44
M. Stamminger
7.3 Graphische Oberfläche
Einfassungsanordnung, BorderLayout (2)
class
class Einfassung
Einfassung {{
public
public static
static void
void main(
main( String[]
String[] args
args )) {{
JFrame
JFrame ff == new
new JFrame("Gitter
JFrame("Gitter -- Anordnung");
Anordnung");
JPanel
JPanel pp == new
new JPanel(new
JPanel(new BorderLayout());
BorderLayout());
f.getContentPane().add(p);
f.getContentPane().add(p);
JButton
JButton bb == new
new JButton("Norden");
JButton("Norden");
p.add(b,
BorderLayout.NORTH);
p.add(b, BorderLayout.NORTH);
bb == new
new JButton("Sueden");
JButton("Sueden");
p.add(b,
p.add(b, BorderLayout.SOUTH);
BorderLayout.SOUTH);
bb == new
new JButton("Westen");
JButton("Westen");
p.add(b,
p.add(b, BorderLayout.WEST);
BorderLayout.WEST);
bb == new
new JButton("Osten");
JButton("Osten");
p.add(b,
p.add(b, BorderLayout.EAST);
BorderLayout.EAST);
bb == new
new JButton("Mitte");
JButton("Mitte");
p.add(b,
p.add(b, BorderLayout.CENTER);
BorderLayout.CENTER);
f.pack();
f.pack();
f.setVisible(
f.setVisible( true
true );
);
}}
}}
Friedrich-Alexander-Universität
Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-45
M. Stamminger
7.3 Graphische Oberfläche
Schachtelanordnung, BoxLayout
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-46
M. Stamminger
7.3 Graphische Oberfläche
Variable Rasteranordnung, GridBagLayout
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-47
M. Stamminger
7.4 Unter der Lupe
Anweisungen mit Label:
ƒ Blockanfänge können mit Namen versehen werden. Namen heißen „Label“
outer:
outer: for
for (int
(int row
row == 0;
0; row
row << numRows;
numRows; row++)
row++) {{
for
for (int
(int col
col == 0;
0; col
col << numCols;
numCols; col++)
col++) {{
...
...
break
break outer;//beendet
outer;//beendet äußere
äußere for-Schleife
for-Schleife
}}
}}
for
for (int
(int i=0;
i=0; ii << myArray.length;
myArray.length; i++)
i++) {{
if
if (myArray[i]
(myArray[i] ==
== null)
null) {{
continue;
continue; //überspringt
//überspringt Rest
Rest der
der Schleife
Schleife
//startet
//startet nächste
nächste Iteration
Iteration
}}
myArray[i].myMethod()
myArray[i].myMethod()
}}
ƒ break verlässt die per Label genannte Schleife, continue startet eine
neue Iteration dieser Schleife. Ohne Label ist die jeweils direkt umgebende
Schleife betroffen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-48
M. Stamminger
7.4 Unter der Lupe
Statischer Initialisierer
ƒ Zusätzlich zur Initialisierung statischer Variablen kann man einen statischen
Initialisierer programmieren.
ƒ Der enthaltene Code wird ausgeführt, sobald die Klasse in die JVM geladen
wird.
ƒ Statische Initialisierer und Initialisierungs-Code für statische Variablen
werden in textueller Ordnung ausgeführt.
class
class Test
Test {{
static
static int
int MAGIC;
MAGIC;
static
static {{
MAGIC
MAGIC == 4711;
4711;
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-49
M. Stamminger
7.4 Unter der Lupe
Initialisierungsreihenfolge (1)
ƒ Auch wenn alle Instanzvariablen sichtbar sind (also nicht erst in späteren
Blöcken deklariert werden), kann ihre Verwendung dennoch unzulässig sein
class
class Test
Test {{
int
int ii == j;
j;
int
int jj == 1;
1;
}}
unzulässiger Vorwärtsverweis
ƒ Vorwärtsreferenzen sind innerhalb von Variableninitialisierern von Instanzoder Klassenvariablen und innerhalb von statischen Initialisierern
unzulässig.
class
class Test
Test {{
Test()
Test() {{ kk == 2;
2; }}
int
int jj == 1;
1;
int
int ii == j;
j;
int
int k;
k;
}}
OK, da Vorwärtsverweis nicht
innerhalb der Initialisierer
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-50
M. Stamminger
7.4 Unter der Lupe
Initialisierungsreihenfolge (2)
ƒ Folge der Abarbeitung in textueller Reihenfolge
class
class Test
Test {{
static
static int
int peek()
peek() {{ return
return j;
j; }}
static
static int
int ii == peek();
peek();
static
int
j
=
1;
static int j = 1;
public
public static
static void
void main
main (String[]
(String[] args)
args) {{
System.out.println(i+",
System.out.println(i+", "+j);
"+j);
}}
}}
OK
Ausgegeben wird 0,1, weil zum Zeitpunkt
der Initialisierung von i auf das dann noch
mit seinem default-Wert initialisierte j
zugegriffen wird. Erst später wird j durch
seinen Initialisierer auf 1 gesetzt.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-51
M. Stamminger
7.4 Unter der Lupe
Initialisierungsreihenfolge (3)
ƒ Lokale Variablen müssen definitiv vor ihrer lesenden Benutzung mit
einem Wert beschrieben werden.
int
int k;
k;
if
if (v
(v >> 00 &&
&& (k
(k == System.in.read())
System.in.read()) >=
>= 0)
0) {{
System.out.println(k);
System.out.println(k);
}}
OK, weil auf jedem Pfad durch den
Code k sicher initialisiert wird.
Die Bedingung kann nur zu true
ausgewertet werden, wenn auch
der zweite Teil ausgewertet wird.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-52
M. Stamminger
7.4 Unter der Lupe
Initialisierungsreihenfolge (4)
ƒ Der Übersetzer betrachtet den Code allerdings nur strukturell und
berücksichtigt außer Wahrheitswerten keine Wert.
int
int k;
k;
int
int nn == 5;
5;
if
if (n
(n >> 2)
2) {{
kk == 3;
3;
}}
System.out.println(k);
System.out.println(k);
int
int k;
k;
if
if (flag)
(flag) {{
kk == 3;
3;
}} else
else {{
kk == 44
}}
System.out.println(k);
System.out.println(k);
Weil n zur Laufzeit den Wert 5 hat,
wird k bei jeder Programmausführung
initialisiert sein. Der Übersetzer
berücksichtigt aber den Wert von n
nicht und "sieht", dass k im else-Fall
nicht initialisiert werden könnte.
OK
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-53
M. Stamminger
7.5 Was geht hier schief?
1. Beispiel
class
class Exp
Exp {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
int
int ii == 10;
10;
int
int jj == 12;
12;
if
if ((i
((i << j)
j) ||
|| (i
(i == 3))
3)) {{
System.out.println("Hello");
System.out.println("Hello");
}}
}}
}}
i=3 ist Zuweisung
mit Ergebnistyp
int. Kann nicht
mit || verknüpft
werden.
Übersetzer meldet
den Fehler.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-54
M. Stamminger
7.5 Was geht hier schief?
2. Beispiel
class
class Exp
Exp {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
int
int ii == 10;
10;
int
int jj == 12;
12;
if
if ((i
((i << j)
j) ||
|| (i
(i == 3)
3) >> 5)
5) {{ }}
System.out.println(i);
System.out.println(i);
}}
}}
Kein syntaktischer Fehler. Vermutlich ist der leere
Rumpf der if-Anweisung nicht beabsichtigt.
Hier wird in jedem Fall „10“ ausgegeben.
Einrücken von println reicht nicht.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-55
M. Stamminger
7.5 Was geht hier schief?
3. Beispiel
class
class Test
Test {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
double
double aa == 5.1;
5.1;
double
double bb == 20.32;
20.32;
double
double cc == 32.998;
32.998;
System.out.println(findAvg(a,b,c));
System.out.println(findAvg(a,b,c));
}}
main ist statische
Methode. Aus
statischem Kontext
kann Objekt-Methode
findAvg nicht
aufgerufen werden.
Übersetzer meldet
den Fehler.
double
double findAvg(double
findAvg(double a,
a, double
double b,
b, double
double c)
c) {{
return
return ((
(( aa ++ cc ++ b)
b) /3.0);
/3.0);
}}
}}
return-Wert nicht
klammern (Codier-Regel)
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-56
M. Stamminger
7.5 Was geht hier schief?
4. Beispiel
class
class Hund
Hund {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
Pudel
Pudel pp == new
new Pudel();
Pudel();
Terrier
Terrier tt == new
new Terrier();
Terrier();
Hund
Hund hh == Hund();
Hund();
hh == p;
p;
pp == h;
h;
pp == (Pudel)
(Pudel) h;
h;
hh == new
new Pudel();
Pudel();
pp == (Pudel)
(Pudel) h;
h;
pp == t;
t;
pp == (Pudel)
(Pudel) t;
t;
}}
}}
new fehlt.
statischer
Typfehler
statisch ok
Laufzeitfehler
statischer
Typfehler
statischer
Typfehler
class
class Pudel
Pudel extends
extends Hund
Hund {{ ...
... }}
class
class Terrier
Terrier extends
extends Hund
Hund {{ ...
... }}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-57
M. Stamminger
7.5 Was geht hier schief?
5. Beispiel
found könnte uninitialisierte lokale Variable
sein. Nur Instanzvariablen und Klassenvariablen
werden automatisch intitialisiert.
Der Übersetzer meldet den Fehler.
class
class Test
Test {{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
int
int index;
index;
boolean
boolean found;
found;
for
for (index
(index == 0;
0; index
index << 10
10 &&
&& !found;
!found; index++)
index++) {{
if
if (index
(index >> Math.PI)
Math.PI) {{
System.out.println(index
System.out.println(index ++ "ist
"ist größer
größer als
als Pi");
Pi");
found
found == true;
true;
}}
}}
}}
}}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-58
M. Stamminger
7.5 Was geht hier schief?
6. Beispiel
main-Methode hat void als Ergebnistyp
Parametername fehlt.
public
public class
class Sum
Sum {{
public
public static
static void
void int
int main(String[])
main(String[]) {{
int
int a[]
a[] == {1,
{1, 2,
2, 3,
3, 4,
4, 5,
5, 6,
6, 7,
7, 8,
8, 9,
9, 10};
10};
lokale Variablen mit gleichem Namen verboten
int
Reihungsgrenzen 0...length-1
int sum
sum == 0;
0;
int
int i;
i;
for
for (int
(int ii == 1;
1; ii <=
<= a.length;
a.length; i+)
i+) {{
++
sum
+=
a[i];
sum += a[i];
System.out.println("The
System.out.println("The sum
sum is:
is: ",
", sum)
sum)
}}
}}
} fehlt
Konkatenation von
Zeichenketten mit +
; fehlt
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-59
M. Stamminger
7.5 Was geht hier schief?
7. Beispiel
Klassennamen beginnen
mit einem Großbuchstaben.
class
class ex
ex {{
...
...
void
void test(int
test(int i,
i, long
long j)
j) {{ ...
... }}
void
void test(long
test(long i,
i, int
int j)
j) {{ ...
... }}
...
...
e.test(1,
e.test(1, 1);
1);
e.test(1L,
e.test(1L, 1);
1);
}}
Beide test-Methoden haben
bei Typwandlung den
gleichen „Abstand“. Es
kann daher nicht statisch
entschieden werden,
welche am spezifischsten
ist. Daher Fehler.
Die zweite test-Methode
passt besser. Alles OK.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2005/06, Folie 0-60
M. Stamminger
Herunterladen