Java Grundkurs Klassen und Objekte

Werbung
Java Schulung
Objektorientierte Programmierung in Java
Teil III: Java Klassen und Objekte
Prof. Dr. Nikolaus Wulff
Referenzvariablen
•
•
Referenzvariablen verweisen auf
(unbenannte) Objekte im Speicher.
Uninitialisierte Variablen enthalten
eine Null-Referenz (null).
a
Point a,b;
•
Objekt
a
b
null
Objekte werden zur Laufzeit erzeugt.
:Point
new Point(0,0);
0
0
a = new Point(1,2);
a
•
Objekte sind anonym.
•
Sie haben eine unveränderliche Identität.
Prof. Dr. Nikolaus Wulff
a:Point
1
2
2
Binden von Referenzvariablen
•
Beim Zuweisen eines Objektes auf eine
Variable wird eine Referenz zugewiesen:
a = new Point(0,0);
b = new Point(3,4);
•
b
Beim Zuweisen von Referenzvariablen
aufeinander werden nur die Referenzen
kopiert, nicht die Objekte:
a = b;
•
a
Vorsicht! Das Objekt kann jetzt über zwei
Pfade geändert werden:
a.set(5,6);
b.set(20,30);
Prof. Dr. Nikolaus Wulff
a
b
0
0
3
4
0
0
3
4
20
30
3
Vergleichen von Objekten
• Beim Vergleichen zweier Referenzvariablen
werden die Referenzen verglichen, nicht die
referenzierten Objekte. Es wird also auf
Objektidentität, nicht auf Inhaltsgleichheit geprüft.
a
b
==
(shallow equality)
c
d
Prof. Dr. Nikolaus Wulff
3
4
3
4
a == b
a != c
d == null
4
Inhaltsvergleich
• Der Inhalt von zwei Objekten wird durch die Methode
equals verglichen.
equals
(deep equality)
new Integer(1) != new Integer(1)
new Integer(1).equals(new Integer(1))
• Bei selbstdefinierten Klassen vergleicht equals (geerbt
von Object) per Default auch nur die Objektidentiät, d.h.
verwendet shallow equality.
• Die Methode equals muss selbst neu überladen werden,
damit sie die gewünschte Funktionalität bietet.
Prof. Dr. Nikolaus Wulff
5
Eine Klasse
class Cell {
private int value = 0;
void setValue(int newValue){
this.value = newValue;
}
int getValue( ) {
return this.value;
}
...
Attribut
Methoden
Klassendefinition
}
Prof. Dr. Nikolaus Wulff
6
Bestandteile einer Klasse
• Einleitung einer Klasse durch Schlüsselwort class:
class EineKlasse { /* Klassenrumpf */ }
• Erzeugung eines Objektes mit new:
EineKlasse a = new EineKlasse();
• Attribute:
class Datengrab {
int i;
float f;
boolean b;
}
Prof. Dr. Nikolaus Wulff
Jede Instanz (jedes Objekt) der
Klasse Datengrab bekommt eine
eigene Kopie der Attribute.
7
Methoden
• Methoden: Verhalten eines Objekts
– Inspizieren und ändern den Zustand eines Objekts.
– Berechnen von Rückgabewerten.
– Anstoßen von weiteren Methoden über das Senden von
Nachrichten an andere Objekte.
– In anderen Sprachen: Funktionen oder Prozeduren.
– Nur innerhalb von Klassen (keine Methode ohne Klasse!).
• Aufruf einer Methode = Senden einer Nachricht:
int x = a.f();
Prof. Dr. Nikolaus Wulff
rufe Methode f von Objekt a bzw.
sende Nachricht f an Objekt a
8
Organisatorisches
• Hands on Tutorien jeweils Mittwochs 15 – 17 Uhr
im Lab4Inf D117 mit Rene Brüggemann.
• Praktikumverschiebung Informatiker Donnerstags
von 13 – 17 auf 14 – 18 Uhr Pool 3.
Prof. Dr. Nikolaus Wulff
9
Parameterliste
•
Die Parameterliste spezifiziert die Typen der Objekte, die als Argumente
an die Methode übergeben werden können.
• Jedes Objekt (Parameter) erhält einen lokalen Namen, über den
innerhalb der Methode auf das Objekt zugegriffen werden kann.
Typ
Name
void reset(Cell c) {
c.setValue(0);
}
•
Beachte: Es werden nicht die Objekte (Kopien), sondern Referenzen auf
die Objekte übergeben!
Cell aCel1 = new Cell();
aCel1.setValue(4);
reset(aCel1);
aCel1.getValue(); ==> 0
Prof. Dr. Nikolaus Wulff
10
Rückgabewerte
• Methoden können Werte bzw. Objektreferenzen
zurückliefern:
Rückgabetyp
Integer berechne(int a, int b) {
int sum = a + b;
return new Integer(sum);
}
Rückgabe
• Mit return wird die Methode sofort verlassen - auch
wenn noch Befehle dahinter folgen!
• Methoden ohne Rückgabe haben den Rückgabetyp void:
void print(int a, int b) {
System.out.println("a + b = " + (a + b));
}
Prof. Dr. Nikolaus Wulff
11
Methodenrumpf
• Variablendeklarationen und -zuweisungen.
void berechne(int a, int b) {
int i;
Deklaration
i = a * b;
Zuweisung
}
• Beachte: Lokale Variablen müssen initialisiert
werden!
void berechne() {
int i;
i++;
Compile-Fehler!
}
Prof. Dr. Nikolaus Wulff
12
Statische Attribute und Methoden
• Attribute und Methoden, die nicht für einzelne Objekte, sondern für
die ganze Klasse definiert sind.
• D.h., jedes Attribut kommt nur einmal pro Klasse vor!
class Person {
static int erzeugtePersonen = 0;
static void printStatistik() {
System.out.println("Erzeugt: " + erzeugtePersonen);
}
}
• Statische Attribute und Methoden können genutzt werden, ohne
Objekte zu erzeugen. Der Zugriff erfolgt über den Klassennamen:
Person.printStatistik();
Person.erzeugtePersonen++;
Prof. Dr. Nikolaus Wulff
Vergleiche:
• System.out.println(...);
• main
13
Statische Attribute
class Person {
static int erzeugtePersonen = 0;
String name;
}
Person
erzeugtePersonen = 0
Klasse mit statischen Attribut
das Objekt kennt seine Klasse
peter
mary
class
class
name = „Peter“
name = „Mary“
Objekte mit Attributen
Prof. Dr. Nikolaus Wulff
14
Konstanten
• Konstanten = finale Werte von Basisdatentypen
– Konstanten zur Übersetzungszeit werden vom Compiler ausgewertet:
final int ANZAHL_MONATE = 12;
– Konstanten zur Laufzeit sind nach der Initialisierung unveränderlich:
final int ZUFALL = (int)(Math.random() * 20);
• final static: nur ein Wert pro Klasse, der seinen Wert nach dem
ersten Laden der Klasse nicht mehr ändert.
• finale Referenzen: können nicht mehr an andere Objekte gebunden
werden
final Integer NULL = new Integer(0);
Prof. Dr. Nikolaus Wulff
15
this und super
• Auf das aktuelle Objekt, auf dem die Methode
ausgeführt wird (an das die Nachricht gesendet
wurde), kann über das Schlüsselwort this
zugegriffen werden.
• Auf das direkte Elternobjekt kann innerhalb einer
Methode mit super zugegriffen werden.
Prof. Dr. Nikolaus Wulff
16
Überladen von Methoden
• Eine Nachricht mit mehreren Signaturen und
Methodenimplementationen.
class SuperWasher {
void wash(Shirt s) { ... }
void wash(Car c) { ... }
void wash(Dog d) { ... }
...
}
SuperWasher sw = new SuperWasher();
Dog aDog = new Dog();
sw.wash(aDog);
• Die Methode wird (statisch) beim Senden der Nachricht
anhand der Parameter ausgewählt.
Prof. Dr. Nikolaus Wulff
17
Kein Überladen bei Rückgabewerten
• Folgende überladene Methoden unterscheiden sich
nur im Rückgabewert:
void washAll() {...}
int washAll() {...}

• Das geht nicht, denn der Compiler kann für diesen
Aufruf nicht bestimmen, welche Methode zu
verwenden ist:
washAll();
Prof. Dr. Nikolaus Wulff
18
Default-Konstruktor
• Konstruktoren dienen zur Erzeugung und
Initialisierung von Objekten einer Klasse.
• Wenn kein Konstruktor angegeben wird, ist
implizit ein Default-Konstruktor (ohne Parameter)
definiert.
class Bird {
String name;
}
class Bird {
String name;
Bird() {
super(); Aufruf der Konstruktors
der Superklasse
}
}
Bird nc = new Bird();
Prof. Dr. Nikolaus Wulff
19
Konstruktordefinition
• Konstruktoren können überladen werden und Parameter erhalten, z.B.
zur Initialisierung von Attributen:
class Worker extends Person {
String name;
Aufruf des Super-Konstruktors ist optional
Worker() {
(erfolgt sonst automatisch vom Compiler)
super();
name = "Noname";
System.out.println("Erzeuge Noname");
};
Worker(String name) {
super();
this.name = name;
System.out.println("Erzeuge " + name);
}
Worker noname = new Worker();
}
Worker peter = new Worker("Peter");
Prof. Dr. Nikolaus Wulff
20
Konstruktorverkettung
• Konstruktoren können sich gegenseitig aufrufen:
class Person {
...
Person(String name, int alter) {
this(name);
Konstruktor dieser Klasse
...
mit Parameter String aufrufen
}
}
• Konstruktoren können Konstruktoren der Superklasse aufrufen:
class Mitglied extends Person {
...
Mitglied(String name, int tarifgruppe) {
super(name); Konstruktor der Superklasse
...
mit Parameter String aufrufen
}
}
Prof. Dr. Nikolaus Wulff
21
Konstruktoraufrufe
•
Beim Erzeugen eines Objektes einer Subklasse wird automatisch der DefaultKonstruktor der Superklasse aufgerufen.
class Person {
Person() {
System.out.println(" Person");
}
}
class Angestellter extends Person {
Angestellter() {
System.out.println(" Angestellter");
}
}
Angestellter peter = new Angestellter();
Ausgabe:
Prof. Dr. Nikolaus Wulff
Person
Angestellter
22
Konstruktor mit Argumenten
• Ein Konstruktor der Superklasse mit Argumenten muss
– als erstes im Konstruktor
– explizit (über super)
aufgerufen werden.
class Person {
Person(String name) {
System.out.println(" Person " + name);
}
}
class Angestellter extends Person {
Angestellter(String name) {
super(name);
System.out.println(" Angestellter " + name);
}
}
Prof. Dr. Nikolaus Wulff
23
Initialisierungsreihenfolge
class Test {
Person p1 = new Person();
Person p2; // null
static int zaehler; // 0
Test() {
p2 = new Person();
}
static {
zaehler = 9;
}
3: per Objekt: Attribute initialisieren
1: per Klasse: Attribute initialisieren
4: per Objekt: Konstruktor ausführen
2: per Klasse: Init-Code ausführen
}
Prof. Dr. Nikolaus Wulff
24
Arrays
• Arrays sind Objekte. Bei der Deklaration wird keine Größe
angegeben, da nur die Referenz abgelegt wird:
int a[];
int[] a;
• Einfache Arrays können direkt erzeugt und initialisiert werden:
int [] a = { 1, 2, 3, 4, 5 };
• Beim Zugriff auf ein Array wird der Index auf Überschreitung der
Array-Größe geprüft:
int x = a[3];
int x = a[567]; ArrayIndexOutOfBounds
• Die Länge des Arrays kann abgefragt werden:
a.length
Prof. Dr. Nikolaus Wulff
25
Arrays von Objekten
• Arrays von Objekten werden so erzeugt und initialisiert:
Person[] a = new Person[20];
for(int i = 0; i < a.length; i++) {
a[i] = new Person("Person Nummer " + i);
}
• Wie bei einfachen Arrays kann direkt initialisiert werden:
Integer[] a = {
new Integer(1),
new Integer(2),
new Integer(3),
};
Prof. Dr. Nikolaus Wulff
26
Mehrdimensionale Arrays
• Mehrdimensionale Arrays werden so deklariert:
int[] a[];
int[][] a;
• Die Initialisierung kann auch hier direkt erfolgen:
int[][] a = { { 1, 2, 3 }, { 5, 6} };
Prof. Dr. Nikolaus Wulff
27
Zeichenketten
•
•
•
•
Zeichenketten sind unveränderliche Objekte der Klasse String.
String-Literale werden durch “” eingefasst.
String-Literale werden automatisch in String-Objekte umgewandelt.
Zeichenketten können auch durch Aufruf eines Konstruktors der
Klasse String erzeugt werden.
String c = "abc";
• Außerdem erzeugen viele Methoden Zeichenketten:
String c = new String("abc");
Integer i = new Integer(789);
String c = i.toString();
Prof. Dr. Nikolaus Wulff
28
Verkettung von Zeichenketten
• Zeichenketten können durch den Operator + verkettet werden:
String c = "Hello " + "World";
• Die Verkettung erzeugt ein neues String-Objekt.
• Werte von Basisdatentypen oder Objekte von Klassen können auch
mit Strings verkettet werden.
String n = "Die Antwort lautet " + 42;
• Sie werden dann implizit in Strings umgewandelt, bei Objekten durch
den Aufruf der Methode toString (definiert in der Klasse
Object).
Prof. Dr. Nikolaus Wulff
29
Sichtbarkeitsbereiche
• Blockstrukturierte Sichtbarkeitsbereiche: Lokale Variablen
sind nach dem Schließen des Blocks nicht mehr sichtbar.
{ // <-- Anfang Scope 1
int x;
x = 12; // Nur x ist sichtbar, q gibt es noch nicht
{
// <-- Anfang Scope 2
int q = 96;
x = q + x; // x kann nicht neu definiert werden!
// x und q sind verfügbar.
}
// <-- Ende Scope 2
// Nur x ist noch sichtbar
// Auf q kann nicht mehr zugegriffen werden.
} // <-- Ende Scope 1
Prof. Dr. Nikolaus Wulff
30
Sichtbarkeitsbereiche
• Gleichnahminge lokale Variablen und Member Variablen
der Klasse müssen per this referenziert werden.
class Foo {
private int x = 2;
// Scope 0 der Membervariablen
public void bar() { // <-- Anfang Scope 1
int x;
x = 12; // Nur x ist sichtbar, q gibt es noch nicht
{
// <-- Anfang Scope 2
int q = 96;
x = q + x; // x kann nicht neu definiert werden!
// x und q sind verfügbar.
}
// <-- Ende Scope 2
// Nur x ist noch sichtbar
// Auf q kann nicht mehr zugegriffen werden.
this.x = x;
// jetzt wird Membervariable x gesetzt
} // <-- Ende Scope 1 der Methode bar...
Prof. Dr. Nikolaus Wulff
31
Bedingter Ausdruck
• Verzweigung, die zu einem Wert evaluiert.
int a, b;
...
b = (a >= 0) ? a : -a;
Bedingung
then
else
• Wird häufig in Projekten verboten, da "schwer zu
lesen". Aquivalent ist eine if - else Verzweigung:
if (a >= 0) {
b = a;
} else {
b = -a;
}
Prof. Dr. Nikolaus Wulff
32
Freispeicherverwaltung
• Java-Objekte werden dynamisch mit new angelegt.
• Sie werden nie explizit gelöscht oder freigegeben.
• Die Java-Maschine schaut regelmäßig (oder nach
Aufforderung) nach, welche Objekte nicht mehr erreichbar
sind (garbage collection) und gibt diese frei.
• Vor der Freigabe wird bei jedem Objekt die Methode
finalize aufgerufen.
Prof. Dr. Nikolaus Wulff
33
Freispeicherverwaltung (2)
• Die virtuelle Maschine prüft, ob ein Objekt noch
von Außen, d.h. ausgehend von der main
Methode noch erreichbar ist.
Ausgangspunkt
main
Speicher der Java Maschine
Prof. Dr. Nikolaus Wulff
X X
X
X
Müll
34
Wiederverwendung
• Vier Alternativen der Wiederverwendung:
– Schreibe die Klasse komplett selber (keine echte
Wiederverwendung).
– Kaufe die fertige Klasse und nutze sie so (volle
Wiederverwendung).
– Benutze eine vorhandene Klasse und binde sie in einer
Komposition in Deine Klasse ein.
– Benutze eine vorhandene Klasse, indem Deine Klasse von ihr erbt
und bestimmte Attribute/Methoden ergänzt oder überschreibt.
• Dies gilt sowohl für einzelne Klassen als auch für
Rahmenwerke (Frameworks) und Bibliotheken.
Prof. Dr. Nikolaus Wulff
35
Komposition vs. Vererbung
Auto
Reifen[]
Fenster[]
Tuer[]
Motor
Shape
draw()
erase()
Circle
draw()
erase()
Square
draw()
erase()
Line
draw()
erase()
Komposition:
Vererbung:
• “hat ein”
• “ist ein”
• “besteht aus”
• verschiedene Objekte/Klasse haben
gemeinsame Eigenschaften
Prof. Dr. Nikolaus Wulff
36
Komposition
MeineKlasse
Vorhandene
Klasse
Vorhandene
Klasse
Vorhandene
Klasse
Vorhandene
Klasse
...
Prof. Dr. Nikolaus Wulff
class Auto {
Motor motor = new Motor(100);
Reifen[] reifen = new Reifen[4];
...
}
•
•
•
•
Ein komponiertes (aggregiertes) Objekt hat Objekte
vorhandenener Klassen als Attribute.
“hat ein” oder “besteht aus”
Flexibilität: Die Objekte können zur Laufzeit
ausgewechselt werden.
Die Komponenten werden meist im Konstruktor
übergeben oder erzeugt.
37
Vererbung: Motivation
class Person{
String name;
String vorname;
int alter;
String getName(){...}
String getId(){...}
}
class Angestellter {
String name;
String vorname;
int alter;
int uid;
String getName(){...}
String getId(){...}
}
Person
name
...
getName()
getId()
class Mitglied {
String name;
String vorname;
int alter;
int tarifgruppe;
...
String getName(){...}
String getId(){...}
int getTarif(){...}
Mitglied
tarifgruppe
Angestellter
uid
}
getTarif()
getId()
Subklasse
Prof. Dr. Nikolaus Wulff
Superklasse
38
Vererbung: Semantik
• “Ist ein”
Die Attribute und Methoden aus der
Superklasse sind automatisch auch
in der Subklasse vorhanden.
Person
name
vorname
alter
getName()
getId()
tarifgruppe
Angestellter
uid
getTarif()
getId()
Mitglied
Prof. Dr. Nikolaus Wulff
Ererbte Methoden können in der
Subklasse redefiniert werden,
z.B. um eine andere Id zu
implementieren (Uxxxxxx).
39
Vererbung: Syntax
class Person {
String name;
String vorname;
int alter;
String getName(){...}
String getId(){...}
}
class Mitglied extends Person {
int tarifgruppe;
neue Attribute hinzufügen
String getTarif(){...}
neue Methoden hinzufügen
}
class Angestellter extends Person {
int uid;
String getId(){...} redefiniert Person.getId()
}
Prof. Dr. Nikolaus Wulff
derselbe Methodenname
dieselbe Parameterliste
derselbe Rückgabetyp
40
Komposition vs. Vererbung
Ist ein Auto ein Motor?
Motor
Auto
Auto
Falsch!
Reifen[]
Fenster[]
Tuer[]
Richtig
Ein Motor wird gestartet,
ein Auto wird gestartet:
Ist deshalb ein Auto so
etwas wie ein Motor?
Prof. Dr. Nikolaus Wulff
Reifen[]
Fenster[]
Tuer[]
Motor
Generell:
 Komposition ist flexibler als
Vererbung (Laufzeit vs.
Übersetzungszeit).
41
Verwendung von final
• Finale Methoden können in Subklassen nicht überschrieben
(redefiniert) werden.
final void print() { ... }
• private Methoden sind implizit final.
• finale Parameter: Dem Parameter darf innerhalb des
Methodenrumpfes kein neuer Wert zugewiesen werden.
void print(final int anzahl) { ... }
• Von einer finalen Klassen kann keine Subklasse gebildet werden.
final class Angestellter { ... }
Prof. Dr. Nikolaus Wulff
42
Polymorphismus
Substitutierbarkeit:
Wann immer ein Objekt der Superklasse erwartet wird (als Parameter,
Empfänger einer Nachricht, ...), kann ein Objekt einer Subklasse benutzt
werden.
Beispiel: Wenn eine Person angezeigt werden soll, kann auch ein Mitglied
(Angestellter, ...) angezeigt werden.
a Circle
draw()
: Shape
a Square
erase()
a Line
Prof. Dr. Nikolaus Wulff
43
Upcast
void moveShape(Shape s) {...; s.draw();}
Cast “nach oben“
in der Vererbungshierarchie
Circle
draw()
erase()
Shape
draw()
erase()
Square
draw()
erase()
Line
draw()
erase()
Referenz auf das
Circle-Objekt
Shape s = (Shape)new Circle(); // explizit
moveShape(new Circle()); // implizit
Prof. Dr. Nikolaus Wulff
44
Statisches vs. Dynamisches Binden
f()
...
Funktion f
f()
...
f()
shape.draw()
Aufrufe statisch an die Funktion gebunden
zur Übersetzungszeit
Dynamischer
BindeMechanismus
...
shape.draw()
...
shape.draw()
Prof. Dr. Nikolaus Wulff
zur Laufzeit
Circle
draw()
Square
draw()
Line
draw()
45
Abstrakte Klassen
• Abstrakte Klassen können abstrakte Methoden enthalten,
d.h. Methoden ohne Methodenrumpf.
• Andere Methoden und Daten können definiert sein.
abstract class ColouredShape {
private Colour c;
public abstract void draw();
public Colour getColour() {
return c;
}
public abstract void erase();
}
Abstrakte
Methoden
• Abstrakten Klassen können nicht instanziert werden.
• Subklassen müssen die abstrakten Methoden
implementieren - oder sie sind selber abstrakt.
Prof. Dr. Nikolaus Wulff
46
Template Pattern
• In einer abstrakten Klasse können die abstrakten
Methoden von anderen Methoden benutzt
werden.
abstract class PrintTemplate {
protected abstract void printHeader();
protected abstract void printFooter();
protected abstract void printContent();
public void print(){
printHeader();
printContent();
printFooter();
}
}
Prof. Dr. Nikolaus Wulff
47
Innere Klassen
• Verschachtelte Klasse einer anderen Klasse.
class Person {
class Adresse { ... }
...
}
class Person {
public String doIt(final int i) {
class Adresse { ... i ... }
}
...
}
• Der Klassenname ist versteckt.
• Objekte der inneren Klasse können auf Attribute,
Methoden der umgebenden Klasse zugreifen.
• Wenn eine innere Klasse innerhalb einer Methode definiert
wird, kann sie auf die Parameter und lokalen Variablen der
Methode zugreifen, wenn diese final sind.
Prof. Dr. Nikolaus Wulff
48
Anonyme innere Klassen
• Innere Klassen könne auch anonym sein.
• Dies wird häufig angewandt bei Schnittstellen.
new WindowAdapter(){
public void windowClosing(WindowEvent e) {...}
}
class MyWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {...}
}
new MyWindowListener();
Prof. Dr. Nikolaus Wulff
49
Schnittstellen
•
•
Die
gilt se Aus
sag
bi s
J
D
sieh
K 1. e
eH
7
PK ,
...
Schnittstellen enthalten keine Implementationen, sondern nur
Methodensignaturen und Konstanten (statische, finale Attribute).
Methodensignatur : = Rückgabetyp + Methodenname + Parameterliste
interface Shape {
Point zero = new Point(0,0);
void erase();
void draw();
}
•
automatisch
static & final
automatisch
public
Eine Schnittstelle kann von einer oder mehreren Schnittstellen erben.
interface ColouredShape extends Shape, Colour {
...
}
Prof. Dr. Nikolaus Wulff
50
Schnittstellen und Implementierung
• Eine Schnittstelle legt ein Protokoll (verstandene Nachrichten) fest.
• Eine Klasse kann eine oder mehrere Schnittstellen implementieren.
Schnittstellen
class Circle implements Shape, Persistent {
pivate int radius;
public void erase() {
...
}
public String draw() {
aus Shape
...
}
public int getRadius(){
...
}
}
Prof. Dr. Nikolaus Wulff
51
Übung
• Erstellen und testen (wie?) Sie den Code für das
folgende Klassenmodell:
Painter
painter
+ Painter
+ Paintable
<<Interface>>
Paintable
(from painter)
paintables : Paintable[]
(from painter)
0..*
drawAll()
addPaintable()
draw()
Achtung:
zwei verschieden
Pakete für Painter
und alle Shapes!
Shape
(from sha pes)
type : String
Shape(type : String)
<<abstract>> draw() : void
shapes
+
+
+
+
Shape
Circle
Square
Line
Prof. Dr. Nikolaus Wulff
Circle
Square
Line
(from sha pes)
(from shapes)
(from shapes)
52
Tip
• Schreiben Sie eine Main Klasse, die den Painter mit
Shapes initialisiert und dann die drawAll Methode
aufruft.
• Die draw Methode der Shapes gibt einfach per
System.out.println den Typ aus.
• Die Zeichenobjekte werden in einem Array verwaltet,
dieses muss dynamisch wachsen!
– Verwenden Sie ein temporäres Hilfsarray.
– (Später lernen Sie Collection Klassen kennen, die uns genau diese
Arbeit abnehmen...)
Prof. Dr. Nikolaus Wulff
53
Übung
• Erstellen Sie eine Dokumentation der Klassen:
– %SRC%>javadoc -d ../doc *
• Navigieren Sie in der Klassendokumentation und passen Sie die
Kommentare in Ihren Methoden und Klassen an.
• Erkunden Sie die verschiedenen Möglichkeiten, die javadoc bietet
(javadoc -? bietet Hilfe)
• Javadoc läßt sich auch als Tool in Eclipse integrieren:
– Run|External Tools|External Tools...|Programm|New
– Location: %JAVA_HOME%\bin\javadoc.exe
– Working Dir: ${project_loc}\src
– Arguments: -d ${project_loc}\doc *
Prof. Dr. Nikolaus Wulff
54
Package Übersicht
Prof. Dr. Nikolaus Wulff
55
Herunterladen