Algorithmen und Datenstrukturen II

Werbung
Algorithmen und Datenstrukturen II
Robert Giegerich
Technische Fakultät
Vorlesung Sommer 2011
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Teil I
Objektorientierte Programmierung in Java
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Traditionelle Konzepte der Softwaretechnik
Folgende traditionelle Konzepte des Software-Engineering werden
u.a. im objektorientierten Ansatz verwendet:
Datenabstraktion (bzw. Datenkapselung) und Information Hiding
Die zentrale Idee der Datenkapselung ist, dass auf eine
Datenstruktur nicht direkt zugegriffen wird, indem etwa einzelne
Komponenten gelesen oder geändert werden, sondern, dass dieser
Zugriff ausschließlich über Zugriffsoperatoren erfolgt. Es werden
also die Implementierungen der Operationen und die
Datenstrukturen selbst versteckt.
Vorteil: Implementierungdetails können beliebig geändert werden,
ohne Auswirkung auf den Rest des Programmes zu haben.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Traditionelle Konzepte der Softwaretechnik (II)
abstrakte Datentypen (ADT)
Realisiert wird die Datenabstraktion duch den Einsatz abstrakter
Datentypen, die Liskov & Zilles (1974) folgendermaßen definierten:
“An abstract data type defines a class of abstract objects
which is completely characterized by the operations
available on those objects. This means that an abstract
data type can be defined by defining the characterizing
operations for that type.”
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Oder etwas prägnanter:
Datentyp
Menge(n) von Werten + Operationen darauf
abstrakter Datentyp
Operationen auf Werten, deren Repräsentation nicht bekannt ist.
Der Zugriff erfolgt ausschließlich über Operatoren.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Oder etwas prägnanter:
Datentyp
Menge(n) von Werten + Operationen darauf
abstrakter Datentyp
Operationen auf Werten, deren Repräsentation nicht bekannt ist.
Der Zugriff erfolgt ausschließlich über Operatoren.
Datenabstraktion fördert die Wiederverwendbarkeit von
Programmteilen und die Wartbarkeit großer Programme.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel: Der ADT Stack
Stack
Eine Datenstruktur über einem Datentyp T bezeichnet man als
Stack1 , wenn die Einträge der Datenstruktur als Folge organisiert
sind und es die Operationen push, pop und peek gibt:
1
bedeutet soviel wie Keller oder Stapel
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel: Der ADT Stack
Stack
Eine Datenstruktur über einem Datentyp T bezeichnet man als
Stack1 , wenn die Einträge der Datenstruktur als Folge organisiert
sind und es die Operationen push, pop und peek gibt:
push fügt ein Element von T stets an das Ende der Folge.
pop entfernt stets das letzte Element der Folge.
peek liefert das letzte Element der Folge, ohne sie zu
verändern.
1
bedeutet soviel wie Keller oder Stapel
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel: Der ADT Stack
Stack
Eine Datenstruktur über einem Datentyp T bezeichnet man als
Stack1 , wenn die Einträge der Datenstruktur als Folge organisiert
sind und es die Operationen push, pop und peek gibt:
push fügt ein Element von T stets an das Ende der Folge.
pop entfernt stets das letzte Element der Folge.
peek liefert das letzte Element der Folge, ohne sie zu
verändern.
Prinzip: last in first out (LIFO)
1
bedeutet soviel wie Keller oder Stapel
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Operatoren
Typen der Operationen
initStack:
push:
T × Stack
pop:
Stack
peek:
Stack
empty:
Stack
Robert Giegerich
A&D II, Vorlesung 2011
−→
−→
−→
−→
−→
Stack
Stack
Stack
T
boolean
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Spezifikation
Spezifikation der Operationen durch Gleichungen. Sei x eine
Variable vom Typ T, stack eine Variable vom Typ Stack:
Spezifikation Stackoperationen
empty (initStack)
empty (push (x, stack))
peek (push (x, stack))
pop (push (x, stack))
Robert Giegerich
A&D II, Vorlesung 2011
=
=
=
=
true
false
x
stack
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Spezifikation
Spezifikation der Operationen durch Gleichungen. Sei x eine
Variable vom Typ T, stack eine Variable vom Typ Stack:
Spezifikation Stackoperationen
empty (initStack)
empty (push (x, stack))
peek (push (x, stack))
pop (push (x, stack))
=
=
=
=
true
false
x
stack
initStack und push sind Konstruktoren (sie konstruieren Terme),
daher gibt es keine Gleichungen für sie.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konzepte der objektorientierten Programmierung
Ziel jeglicher Programmierung ist:
Modellierung von Ausschnitten der Realität
sachgerechte Abstraktion
realitätsnahes Verhalten
Nachbildung von Ähnlichkeit im Verhalten
Klassifikation von Problemen
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Phylogenetische Klassifizierung
Tiere
HH
?
Insekten
Robert Giegerich
A&D II, Vorlesung 2011
?
Säugetiere
Fische
@
H
HH
HH
j
@
@
R
@
?
@
@
R
@
?
@
R
@
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Ökonomische Klassifizierung
Tiere
HH
?
Zuchttiere
Robert Giegerich
A&D II, Vorlesung 2011
?
Störtiere
Wild
@
H
HH
HH
j
@
@
R
@
?
@
@
R
@
?
@
R
@
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Drei Vorgehensweisen im Systementwurf
1
die funktionsorientierte
2
die datenorientierte
3
die objektorientierte
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Der Kerngedanke des objektorientierten Ansatzes besteht darin,
Daten und Funktionen zu verschmelzen. Im ersten Schritt werden
die Daten abgeleitet, im zweiten Schritt werden den Daten die
Funktionen zugeordnet, die sie manipulieren. Die entstehenden
Einheiten aus Daten und Funktionen werden Objekte genannt.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Der Kerngedanke des objektorientierten Ansatzes besteht darin,
Daten und Funktionen zu verschmelzen. Im ersten Schritt werden
die Daten abgeleitet, im zweiten Schritt werden den Daten die
Funktionen zugeordnet, die sie manipulieren. Die entstehenden
Einheiten aus Daten und Funktionen werden Objekte genannt.
Wir schränken den Begriff Objektorientierung gemäß folgender
Gleichung von Coad & Yourdon weiter ein:
Objektorientierung
Objektorientierung =
Robert Giegerich
A&D II, Vorlesung 2011
Klassen und Objekte
+ Kommunikation mit Nachrichten
+ Vererbung
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Einfachvererbung
Object
@
System
?
Math
@
R
@
Point
@
@
R
@
...
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Mehrfachvererbung
...
@
@
R
@
Tiere
@
@
R
@
Pflanzen
Fleischfresser
@
@
R
@
...
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Klasse Object
Object oref = new Point();
oref = "eine Zeichenkette";
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konstruktoren (I)
neu erzeugten Objekten wird ein Anfangszustand zugewiesen
Datenfelder können bei Deklaration initialisiert werden
oft ist aber mehr als nur einfache Dateninitialisierung nötig
Konstruktoren bewerkstelligen mehr als einfache
Initialisierungen
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konstruktoren (II)
Konstruktoren
methodenähnlich
haben denselben Namen wie die von ihnen initialisierte Klasse
keine oder mehrere Parameter
keinen Rückgabetyp
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konstruktoren (II)
Konstruktoren
methodenähnlich
haben denselben Namen wie die von ihnen initialisierte Klasse
keine oder mehrere Parameter
keinen Rückgabetyp
Bei der Objekterzeugung werden
1 den Instanzvariablen ihre voreingestellten Anfangswerte
zugewiesen
2 Initialisierungsausdrücke der Instanzvariablen berechnet und
zugewiesen
3 der Konstruktor aufgerufen
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Konstruktoren und Initialisierungsblöcke)
public class Circle {
int x=0, y=0, r=1;
static int numCircles=0;
public Circle() {
numCircles++;
}
public double circumference() {
return 2*Math.PI*r;
}
public double area() {
return Math.PI*r*r;
}
public static void main(String[] args) {
Circle c = new Circle();
System.out.println(c.r);
System.out.println(c.circumference());
System.out.println(c.area());
System.out.println(numCircles);
}
Robert Giegerich
}
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konstruktor mit Parametern
Beispiel (Konstruktor mit drei Parametern)
public Circle(int xCoord, int yCoord, int radius) {
numCircles++;
x = xCoord;
y = yCoord;
r = radius;
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
mit this-Referenz
Beispiel
public Circle(int x, int y, int r) {
numCircles++;
this.x = x;
this.y = y;
this.r = r;
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Überladen von Konstruktoren)
public class Circle {
int x = 0, y = 0, r = 1;
static int numCircles;
public Circle() {
numCircles++;
}
public Circle(int x, int y, int r) {
this();
this.x = x;
this.y = y;
this.r = r;
}
public Circle(int r) {
this(0,0,r);
}
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle(1,1,2);
Circle c3 = new Circle(3);
System.out.println(numCircles);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Komplexe Initialisierung von Klassenvariablen
Beispiel (Flanagan [3], S. 59)
public class Circle {
public static double[] sines = new double[1000];
public static double[] cosines = new double[1000];
static {
double x, delta_x;
int i;
delta_x = (Math.PI/2)/(1000-1);
for(i=0,x=0; i<1000; i++,x+=delta_x) {
sines[i] = Math.sin(x);
cosines[i] = Math.cos(x);
}
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Java-Klassen als Realisierung und Implementierung von
abstrakten Datentypen
Durch den Modifizierer private können wir
Implementierungsdetails verstecken, denn als private deklarierte
Attribute und Methoden sind nur in der Klasse selbst zugreifbar2 .
Folgende Klasse implementiert einen ADT Stack mittels eines
Feldes:
2
Synonyme für Zugreifbarkeit sind: Gültigkeit bzw. Sichtbarkeit.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Stack)
public class Stack {
private Object[] stack;
private int top = -1;
private static final int CAPACITY = 10000;
/** liefert einen leeren Keller. */
public Stack() {
stack = new Object[CAPACITY];
}
/** legt ein Objekt im Keller ab und liefert dieses Objekt
zusaetzlich zurueck. */
public Object push(Object item) {
stack[++top] = item;
return item;
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Stack)
/** entfernt das oberste Objekt vom Keller und liefert es zurueck.
Bei leerem Keller wird eine Fehlermeldung ausgegeben und
null zurueckgeliefert. */
public Object pop() {
if (empty()) {
System.out.println("Method pop: empty stack");
return null;
}
else
return stack[top--];
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Stack)
/** liefert das oberste Objekt des Kellers, ohne ihn zu veraendern.
Bei leerem Keller wird eine Fehlermeldung ausgegeben und
null zurueckgeliefert. */
public Object peek() {
if (empty()) {
System.out.println("Method peek: empty stack");
return null;
}
else
return stack[top];
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Stack)
/** liefert true genau dann, wenn der Keller leer ist. */
public boolean empty() {
return (top == -1);
}
/** liefert die Anzahl der Elemente des Kellers. */
public int size() {
return top+1;
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Der Dokumentationskommentar /** ... */ wird zur
automatischen Dokumentierung der Attribute und Methoden einer
Klasse benutzt. Das Programm javadoc generiert ein HTML-File,
in dem alle sichtbaren Attribute und Methoden mit deren
Parameterlisten aufgezeigt und dokumentiert sind.
> javadoc Stack.java
Dieses HTML-File ist der Vertrag (die Schnittstelle) der Klasse und
entspricht dem ADT Stack, wobei die Operationen bzw. Methoden
allerdings nur natürlichsprachlich spezifiziert wurden. Die obige
verbale Spezifikation entspricht weitgehend der der vordefinierten
Java-Klasse Stack (genauer java.util.Stack). Man beachte,
dass (aus diesem Grund) die obige Spezifikation von der
Gleichungsspezifikation aus dem Unterabschnitt ?? abweicht.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Methoden in Java
1
Methoden und Signaturen
2
Überladen von Methoden
3
Wertübergabe (call by value)
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Signaturen, Überladen von Methoden
Methoden können wie Konstruktoren überladen werden
jede Methode besitzt eine Signatur, die ihren Namen sowie die
Anzahl und Typen der Parameter definiert
Überladen von Methoden
Zwei Methoden können denselben Namen haben, wenn ihre
Signaturen unterschiedliche Anzahlen oder Typen von Parametern
aufweisen.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
call by value
Die Parameterübergabe zu Methoden erfolgt in Java durch
Wertübergabe (call by value). D.h., dass Werte von
Parametervariablen in einer Methode Kopien der vom Aufrufer
angegebenen Werte sind. Das nächste Beispiel verdeutlicht dies.
Beispiel
public class CallByValue {
public static int sqr(int i) {
i = i*i;
return(i);
}
public static void main(String[] args) {
int i = 3;
System.out.println(sqr(i));
System.out.println(i);
}
> java CallByValue
9
3
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Allerdings ist zu beachten, dass nicht Objekte, sondern
Objektreferenzen übergeben werden. Wir betrachten unser
Standardbeispiel Circle in folgender abgespeckter Form (gemäß
der Devise, Implementierungsdetails zu verbergen, werden die
Datenfelder als private deklariert).
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public class Circle {
private int x,y,r;
public Circle(int x, int y, int r) {
this.x = x;
this.y = y;
this.r = r;
}
public double circumference() {
return 2 * Math.PI * r;
}
public double area() {
return Math.PI * r * r;
}
public static void setToZero (Circle arg) {
arg.r = 0;
arg = null;
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Fortsetzung)
public static void main(String[] args) {
Circle kreis = new Circle(10,10,1);
System.out.println("vorher : r = "+kreis.r);
setToZero(kreis);
System.out.println("nachher: r = "+kreis.r);
}
}
> java Circle
vorher : r = 1
nachher: r = 0
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Fortsetzung)
public static void main(String[] args) {
Circle kreis = new Circle(10,10,1);
System.out.println("vorher : r = "+kreis.r);
setToZero(kreis);
System.out.println("nachher: r = "+kreis.r);
}
}
> java Circle
vorher : r = 1
nachher: r = 0
Dieses Verhalten entspricht jedoch nicht der Parameterübergabe call by
reference, denn bei der Wertübergabe wird eine Kopie der Referenz erzeugt und
die ursprüngliche Referenz bleibt erhalten. Bei call by reference würde die
übergebene Referenz eben nicht kopiert und daher in der Methode setToZero
auf null gesetzt.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Unterklassen und Vererbung in Java
Wir wollen die Klasse Circle so erweitern, dass wir deren
Instanzen auch graphisch darstellen können.
Erweiterung der Klasse Circle zu der neuen Klasse
GraphicCircle
durch das Schlüsselwort extends wird GraphicCircle eine
Unterklasse von Circle
GraphicCircle erweitert die (Ober-)Klasse Circle
die Klasse GraphicCircle erbt alle Attribute und Methoden
von Circle, die nicht als private deklariert sind
Attribute und Methoden, die als protected deklariert sind,
bleiben (nur) für die Unterklasse zugreifbar
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
import java.awt.Color;
import java.awt.Graphics;
public class GraphicCircle extends Circle {
protected Color outline;
// Farbe der Umrandung
protected Color fill;
// Farbe des Inneren
public GraphicCircle(int x,int y,int r,Color outline) {
super(x,y,r);
this.outline = outline;
this.fill = Color.lightGray;
}
public GraphicCircle(int x,int y,int r,Color outline,Color fill) {
this(x,y,r,outline);
this.fill = fill;
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public void draw(Graphics g) {
g.setColor(outline);
g.drawOval(x-r, y-r, 2*r, 2*r);
g.setColor(fill);
g.fillOval(x-r, y-r, 2*r, 2*r);
}
public static void main(String[] args) {
GraphicCircle gc = new GraphicCircle(0,0,100,Color.red,Color.blue);
double area = gc.area();
System.out.println(area);
Circle c = gc;
double circumference = c.circumference();
System.out.println(circumference);
GraphicCircle gc1 = (GraphicCircle) c;
Color color = gc1.fill;
System.out.println(color);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Color und Graphics
Color und Graphics sind vordefinierte Klassen, die durch import
zugreifbar gemacht werden (vgl. Abschnitt ??). Diese Klassen
werden z.B. in [3] beschrieben. Zum Verständnis reicht es hier zu
wissen, dass der erste Konstruktor den Konstruktor seiner
Oberklasse aufruft (vgl. Abschnitt ??) und das Kreisinnere die
Farbe hellgrau erhält, sowie, dass die Methode draw einen farbigen
Kreis zeichnet.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Da GraphicCircle alle Methoden von Circle erbt, können wir
z.B. den Flächeninhalt eines Objektes gc vom Typ GraphicCircle
berechnen durch:
Beispiel
double area = gc.area();
Jedes Objekt gc vom Typ GraphicCircle ist ebenfalls ein Objekt
vom Typ Circle bzw. vom Typ Object. Deshalb sind folgende
Zuweisungen korrekt.
Beispiel
Circle c = gc;
double area = c.area();
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Man kann c durch casting3 in ein Objekt vom Typ
GraphicCircle zurückverwandeln.
Beispiel
GraphicCircle gc1 = (GraphicCircle)c;
Color color = gc1.fill;
Die oben gezeigte Typumwandlung funktioniert nur, weil c
tatsächlich ein Objekt vom Typ GraphicCircle ist.
3
explizite Typumwandlung
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Überschreiben von Methoden und Verdecken von
Datenfeldern
Wir betrachten folgendes Java-Programm (Arnold & Gosling [1],
S. 66):
Beispiel
public class SuperShow {
public String str = "SuperStr";
public void show() {
System.out.println("Super.show: "+str);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel (Fortsetzung)
public class ExtendShow extends SuperShow {
public String str = "ExtendStr";
public void show() {
System.out.println("Extend.show: "+str);
}
public static void main(String[] args) {
ExtendShow ext = new ExtendShow();
SuperShow sup = ext;
sup.show();
ext.show();
System.out.println("sup.str = "+sup.str);
System.out.println("ext.str = "+ext.str);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Verdecken von Datenfeldern
Jedes ExtendShow-Objekt hat zwei String-Variablen, die beide
str heißen und von denen eine ererbt wurde. Die neue Variable
str verdeckt die ererbte; wir sagen auch die ererbte ist verborgen.
Sie existiert zwar, man kann aber nicht mehr durch Angabe ihres
Namens auf sie zugreifen.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Überschreiben von Methoden
die Methode show() der Klasse ExtendShow überschreibt die
gleichnamige Methode der Oberklasse
die Implementierung der Methode der Oberklasse wird durch
eine neue Implementierung der Unterklasse ersetzt
dabei müssen Signatur und Rückgabetyp dieselben sein
überschreibende Methoden besitzen ihre eigenen
Zugriffsangaben
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Überschreiben von Methoden
Wenn eine Methode von einem Objekt aufgerufen wird, dann
bestimmt immer der tatsächliche Typ des Objektes, welche
Implementierung benutzt wird. Bei einem Zugriff auf ein Datenfeld
wird jedoch der deklarierte Typ der Referenz verwendet. Daher
erhalten wir folgende Ausgabe beim Aufruf der main-Methode:
Beispiel
> java ExtendShow
Extend.show: ExtendStr
Extend.show: ExtendStr
sup.str = SuperStr
ext.str = ExtendStr
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Die Objektreferenz super
Das Schlüsselwort super kann in allen objektbezogenen Methoden
und Konstruktoren verwendet werden. In Datenfeldzugriffen und
Methodenaufrufen stellt es eine Referenz zum aktuellen Objekt als
eine Instanz seiner Oberklasse dar. Wenn super verwendet wird, so
bestimmt der Typ der Referenz über die Auswahl der zu
verwendenden Methodenimplementierung. Wir illustrieren dies
wieder an einem Beispielprogramm.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
super Beispiel
Beispiel
public class T1 {
protected int x = 1;
protected String s() {
return "T1";
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public class T2 extends T1 {
protected int x = 2;
protected String s() {
return "T2";
}
protected void test() {
System.out.println("x= "+x);
System.out.println("super.x= "+super.x);
System.out.println("((T1)this).x= "+((T1)this).x);
System.out.println("s(): "+s());
System.out.println("super.s(): "+super.s());
System.out.println("((T1)this).s(): "+((T1)this).s());
}
public static void main(String[] args) {
new T2().test();
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
> java T2
x= 2
super.x= 1
((T1)this).x= 1
s(): T2
super.s(): T1
((T1)this).s(): T2
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Konstruktoren in Unterklassen
In Konstruktoren der Unterklasse kann direkt einer der
Oberklassenkonstruktoren mittels des super() Konstruktes
aufgerufen werden.
Achtung: Der super-Aufruf muss die erste Anweisung des
Konstruktors sein!
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Wird kein Oberklassenkonstruktor explizit aufgerufen, so wird
der parameterlose Konstruktor der Oberklasse automatisch
aufgerufen, bevor die Anweisungen des neuen Konstruktors
ausgeführt werden.
Verfügt die Oberklasse nicht über einen parameterlosen
Konstruktor, so muss ein Konstruktor der Oberklasse explizit
mit Parametern aufgerufen werden, da es sonst einen Fehler
bei der Übersetzung gibt.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Wird kein Oberklassenkonstruktor explizit aufgerufen, so wird
der parameterlose Konstruktor der Oberklasse automatisch
aufgerufen, bevor die Anweisungen des neuen Konstruktors
ausgeführt werden.
Verfügt die Oberklasse nicht über einen parameterlosen
Konstruktor, so muss ein Konstruktor der Oberklasse explizit
mit Parametern aufgerufen werden, da es sonst einen Fehler
bei der Übersetzung gibt.
Ausnahme: Wird in der ersten Anweisung eines Konstruktors ein
anderer Konstruktor derselben Klasse mittels this
aufgerufen, so wird nicht automatisch der
parameterlose Oberklassenkonstruktor aufgerufen.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Java liefert einen voreingestellten parameterlosen Konstruktor für
eine erweiternde Klasse, die keinen Konstruktor enthält. Dieser ist
äquivalent zu:
Beispiel
public class ExtendedClass extends SimpleClass {
public ExtendedClass () {
super();
}
}
Der voreingestellte Konstruktor hat dieselbe Sichtbarkeit wie seine
Klasse.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Ausnahme: Enthält die Oberklasse keinen parameterlosen
Konstruktor, so muss die Unterklasse mindestens
einen Konstruktor bereitstellen.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Reihenfolgeabhängigkeit von Konstruktoren
Wird ein Objekt erzeugt, so werden zuerst alle seine Datenfelder
auf voreingestellte Werte initialisiert. Jeder Konstruktor durchläuft
dann drei Phasen:
Aufruf des Konstruktors der Oberklasse.
Initialisierung der Datenfelder mittels der
Initialisierungsausdrücke.
Ausführung des Rumpfes des Konstruktors.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public class X {
protected String infix = "fel";
protected String suffix;
protected String alles;
public X() {
suffix = infix;
alles = verbinde("Ap");
}
public String verbinde(String original) {
return (original+suffix);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public class Y extends X {
protected String extra = "d";
public Y() {
suffix = suffix+extra;
alles = verbinde("Biele");
}
public static void main(String[] args) {
new Y();
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Die folgende Tabelle zeigt die Inhalte der Datenfelder beim Aufruf
der main-Methode (d.h. des Y-Konstruktors).
Schritt
0
1
2
3
4
5
6
Robert Giegerich
A&D II, Vorlesung 2011
Aktion
Datenfelder auf Voreinstellungen
Y-Konstruktor aufgerufen
X-Konstruktor aufgerufen
X-Datenfeld initialisiert
X-Konstruktor ausgeführt
Y-Datenfeld initialisiert
Y-Konstruktor ausgeführt
infix
extra
suffix
alles
fel
fel
fel
fel
d
d
fel
fel
feld
Apfel
Apfel
Bielefeld
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
jede Klasse, die eine abstrakte Methode enthält, ist selbst
abstrakt und muss als solche gekennzeichnet werden;
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
jede Klasse, die eine abstrakte Methode enthält, ist selbst
abstrakt und muss als solche gekennzeichnet werden;
jede abstrakte Klasse muss mindestens eine abstrakte
Methode besitzen;
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
jede Klasse, die eine abstrakte Methode enthält, ist selbst
abstrakt und muss als solche gekennzeichnet werden;
jede abstrakte Klasse muss mindestens eine abstrakte
Methode besitzen;
man kann von einer abstrakten Klasse keine Objekte erzeugen;
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
jede Klasse, die eine abstrakte Methode enthält, ist selbst
abstrakt und muss als solche gekennzeichnet werden;
jede abstrakte Klasse muss mindestens eine abstrakte
Methode besitzen;
man kann von einer abstrakten Klasse keine Objekte erzeugen;
von einer Unterklasse einer abstrakten Klasse kann man
Objekte erzeugen – vorausgesetzt sie überschreibt alle
abstrakten Methoden der Oberklasse und implementiert diese;
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Abstrakte Klassen und Methoden
Es gilt:
eine abstrakte Methode hat keinen Rumpf;
jede Klasse, die eine abstrakte Methode enthält, ist selbst
abstrakt und muss als solche gekennzeichnet werden;
jede abstrakte Klasse muss mindestens eine abstrakte
Methode besitzen;
man kann von einer abstrakten Klasse keine Objekte erzeugen;
von einer Unterklasse einer abstrakten Klasse kann man
Objekte erzeugen – vorausgesetzt sie überschreibt alle
abstrakten Methoden der Oberklasse und implementiert diese;
eine Unterklasse, die nicht alle abstrakten Methoden der
Oberklasse implementiert ist selbst wieder abstrakt.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel Benchmark
Beispiel
public abstract class Benchmark {
public abstract void benchmark();
public long repeat(int count) {
long start = System.currentTimeMillis();
for(int i=0; i<count; i++)
benchmark();
return (System.currentTimeMillis()-start);
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Beispiel
public class MethodBenchmark extends Benchmark {
public void benchmark() { }
public static void main(String[] args) {
int count = Integer.parseInt(args[0]);
long time = new MethodBenchmark().repeat(count);
System.out.println(count+" Methodenaufrufe in "+time+
" Millisekunden");
}
}
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Konzepte Softwaretechnik
Konzepte OOP
Konstruktoren
ADT in Java
Methoden in Java
Unterklassen und Vererbung
Weiterführende Literatur
K. Arnold, J. Gosling: JavaTM - Die Programmiersprache.
Addison-Wesley, 1996.
T.H. Cormen, C.E. Leierson, R.L. Rivest: Introduction to
Algorithms. MIT Press, 1990.
D. Flanagan: Java in a Nutshell. O’Reilly & Associates Inc.,
1996.
F. Jobst: Programmieren in Java. Hanser Verlag, 1996.
H. Klaeren: Vom Problem zum Programm. 2.Auflage,
B.G. Teubner Verlag, 1991.
K. Echtle, M. Goedicke: Lehrbuch der Programmierung mit
Java. dpunkt-Verlag, 2000.
Robert Giegerich
A&D II, Vorlesung 2011
Universität Bielefeld
Herunterladen