Praktikum: Objektorientierte Programmierung mit Java

Werbung
Hochschule für Angewandte Wissenschaften Hamburg
Hamburg University of Applied Sciences
Department Informations- und Elektrotechnik
Prof. Dr. Thomas Klinker
Praktikum:
Objektorientierte Programmierung mit Java
Termin 1: Klassen und Objekte
Aufgabe 1
Schreiben Sie ein Programm, das einen Satz einliest und die Häufigkeit der Buchstaben zählt,
ohne auf Groß-/Kleinschreibung zu achten.
− Verwenden Sie in Ihrem Programm die vorgegebenen Klassen "Counter" und "Letters"
− Geben Sie das Ergebnis so aus, wie es die Konsolenausgabe zeigt.
import java.io.*;
//-----------------------------------------------------------class Counter {
static int total = 0;
int count;
Counter() { count = 0; }
void inc() { count++; total++; }
void clear() { count = 0; }
}
//-----------------------------------------------------------class Letters {
Counter cnt[] = new Counter[26];
...
...
}
//-----------------------------------------------------------public class Test {
public static void main(String[] args) {
Letters le;
Praktikum OOP mit Java,
...
2/11
Prof. Dr. Th. Klinker
// Satz einlesen
le.count();
le.display();
}
}
Auf der Konsole:
Das ist ein Test.<Ret>
Total: 13
s 3
t 3
e 2
i 2
a 1
d 1
n 1
Aufgabe 2
Gegeben ist folgender Programmrumpf:
import java.math.*;
//-----------------------------------------------------------class Wuerfel {
// Ein Wuerfel
int zahl;
Wuerfel() { zahl = 0; }
void wuerfeln() { zahl = 1 + (int)(6.0 * Math.random()); }
}
//-----------------------------------------------------------class NWuerfel {
// N Wuerfel
...
...
}
//-----------------------------------------------------------public class Test {
public static void main(String[] args) {
NWuerfel myWuerfel = new NWuerfel(2);
myWuerfel.wuerfeln();
myWuerfel.display();
myWuerfel.wuerfeln();
myWuerfel.display();
}
}
2.1 Vervollständigen Sie die Klasse "NWuerfel" so, dass die Ausführung von "main" zu einer Konsolenausgabe in der gegebenen
Form führt. Die Würfelergebnisse sind dabei zufällig und können
sich natürlich von der dargestellten Ausgabe unterscheiden.
Verwenden Sie in Ihrer Klasse "NWuerfel" einen Array von
Instanzen der Klasse "Wuerfel".
Auf der Konsole:
2 4
5 2
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
2.2 Ändern Sie das Programm aus 2.1 so, dass es sechs
Lottozahlen und eine Zusatzzahl ausgibt. Die Lottozahlen sind dabei zufällig und können sich von der
Vorgabe unterscheiden. Achten Sie bei Ihrer Lösung
darauf, dass jede Zahl nur einmal vorkommen kann.
3/11
Auf der Konsole:
38 47 2 43 45 25
12 29 42 28 31 4
46
13
Aufgabe 3
Schreiben Sie ein Programm, dass alle Rechenoperationen ermöglicht, die mit Matrizen
ausgeführt werden können. Die Größe der Matrizen soll dabei beliebig sein. Konstruieren Sie
eine geeignete Klasse "Matrix", die folgende Membervariablen haben soll:
- die Zahl der Zeilen der Matrix
- die Zahl der Spalten der Matrix
- ein zweidimensionales Array (Elemente vom Typ double), in dem die Elemente der Matrix
abgespeichert werden.
In der Klasse "Matrix" sind nun geeignete Methoden zu programmieren, so dass folgende
mathematische Operationen mit Matrizen ausgeführt werden können:
-
Matrix-Addition,
Matrix-Subtraktion,
Matrix-Multiplikation und
die Multiplikation einer Matrix mit einem Skalar (d.h. einer Zahl vom Typ double).
Bei der Ausführung dieser Operationen muss natürlich zuerst geprüft werden, ob die
Dimensionen der beteiligten Matrizen die jeweilige Operation überhaupt erlauben. MatrixAddition ist beispielsweise nur möglich, wenn die Dimensionen (Zahl der Zeilen und Zahl der
Spalten) der beiden Matrizen identisch sind. Oder bei der Matrix-Multiplikation muss die
Zahl der Spalten des linken Operanden gleich der Zahl der Zeilen des rechten Operanden sein.
Schreiben Sie eine geeignete Ausnahmebehandlung (Exception Handling), die diese
Fehlerfälle abfängt, und einen Absturz des Programms verhindert.
In dieser Aufgabe soll der Umgang mit Klassen geübt werden, die dynamisch Speicher
allokieren. Sorgen Sei also dafür, dass die Klasse Matrix über geeignete Konstruktoren, ggf.
auch einen Kopierkonstruktor verfügt. (Bei diesem muss unbedingt ein deep copying
durchgeführt werden!)
Für die Ein- und Ausgabe der Matrizen sollen geeignete Methoden programmiert werden, die
die zum einen eine benutzerfreundliche Eingabe einer Matrix mit geeigneten Führungstexten,
sowie die formatierte Ausgabe einer Matrix ermöglichen. Ein- und Ausgabe erfolgen über die
Konsole.
Im Hauptprogramm soll ein Menu programmiert werden, in dem der Benutzer auswählen
kann, welche Matrix-Operation er ausführen will. Dann werden die Matrizen eingegeben und
das Ergebnis angezeigt. Dies soll wiederholt möglich sein, bis der Benutzer sich entscheidet,
das Programm zu beenden.
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
4/11
Termin 2: Aggregation und Vererbung
Aufgabe 1
Schreiben Sie ein Programm, das die Abläufe in einer Bibliothek verwaltet. Zu diesem Zweck
soll eine Klasse MyLibrary entworfen werden, die folgende drei Instanzvariablen hat:
private String name;
private ArrayList<Book> books;
private ArrayList<Person> people;
//
//
//
//
name of library
list of all books
list of all persons who
can check out a book
Die Liste aller Bücher der Bibliothek, sowie die Liste aller Personen, die Bücher ausleihen
können, sollen also mittels der generischen Collection ArrayList<> archiviert werden.
Weiter soll eine Klasse Person entworfen werden, die alle relevanten Daten einer Person
beschreibt. Sie sollte folgende Instanzvariablen haben:
private String name;
private int maximumBooks;
//
//
//
//
//
name of person
maximum number of books the
person can check out.
Can vary from person to
person
Schließlich soll eine Klasse Book entworfen werden, die alle relevanten Daten eines Buchs
der Bibliothek erfasst. Sie sollte folgende Instanzvariablen haben:
private String title;
private String author;
private Person person;
// title of book
// author of book
// person who has checked out a book
Die Instanzvariable person beschreibt hierbei die Person, an die gegebenenfalls das
betreffende Buch ausgeliehen wurde.
Bei der Verwaltung der Abläufe in der Bibliothek sollten nun folgende Operationen möglich
sein, die als Methoden der Klasse MyLibrary zu implementieren sind:
-
Hinzufügen eines Buchs zum Bestand der Bibliothek
Entfernen eines Buch aus dem Bestand der Bibliothek
Hinzufügen einer ausleihberechtigten Person
Entfernen einer ausleihberechtigten Person
Ausleihen eines Buchs an eine bestimmte Person
Rückgabe eines ausgeliehenen Buchs
Ausgabe aller Bücher, die eine bestimmte Person ausgeliehen hat.
Ausgabe aller verfügbaren (also nicht ausgeliehenen) Bücher
Ausgabe des gesamten Status der Bibliothek: Name der Bibliothek, Liste aller Bücher
mit Angabe der Person, die ein Buch eventuell ausgeliehen hat und Liste aller
Personen mit Angabe, wie viele Bücher die betreffende Peson ausgeliehen hat.
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
5/11
Es können auch noch weitere Operationen hinzugefügt werden, die Sie für sinnvoll halten. In
dem Hauptprogramm main() soll nun als erstes eine Instanz der Klasse MyLibrary
erzeugt werden, die die zunächst leere Bibliothek repräsentiert. Programmieren Sie dann in
main() ein Menu, in dem der Benutzer auswählen kann, welche Operation er ausführen will
(Hinzufügen eines Buchs zum Bestand der Bibliothek, Entfernen eines Buchs aus dem
Bestand der Bibliothek, usw.), und das die Eingabe und Ausgabe der notwendigen Daten auf
der Konsole ermöglicht. Die Ein- und Ausgabe kann dabei einfach gehalten werden, da I/O
über die Konsole nur ein Provisorium ist.
Schreiben Sie das Programm unbedingt gemäß dem Model-View-Controller (MVC)
Architekturmuster! Das heißt insbesondere, die Datenhaltung in der Bibliothek und die Einund Ausgabe auf der Konsole (Visualisierung der Daten) sollen so weit wie möglich getrennt
werden. Die Methoden der Klasse MyLibrary nehmen also nur die entsprechenden
Einträge vor, die gesamte Ein- und Ausgabe erfolgt jedoch im Hauptprogramm. So könnte die
Deklaration der Methode, die alle Bücher auflistet, die eine bestimmte Person p ausgeliehen
hat wie folgt aussehen:
public ArrayList<Book> getBooksForPerson(Person p)
Die Methode liefert also eine ArrayList mit allen von der Person p ausgeliehenen Büchern
zurück, die Ausgabe der Liste erfolgt dann im Hauptprogramm. Der wesentliche Vorteil
dieser Vorgehensweise besteht darin, dass wenn man später das Programm mit einer anderen,
komfortableren Oberfläche (z.B. mit dem Swing-Toolset) versehen will, muss man nur an
einer Stelle im Programm ändern.
Achten Sie darauf, Ihr Programm ausreichend zu testen! Ein Buch, das bereits ausgeliehen
ist, kann z.B. nicht noch einmal an eine andere Person ausgeliehen werden. Ein Buch das
ausgeliehen ist, kann nicht aus der Bibliothek entfernt werden, sondern muss erst
zurückgegeben werden. Eine Person die bereits ihre maximale Zahl an Büchern ausgeliehen
hat, kann nicht noch ein weiteres Buch ausleihen, usw. Testen Sie also alle denkbaren
Situationen aus, und stellen Sie so sicher, dass sich Ihr Programm stets korrekt verhält.
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
6/11
Aufgabe 2
Vervollständigen und testen Sie die nachfolgenden Klassen "Person", Student" und
"Semestersprecher". Mit diesen Klassen soll "main()" zu der gegebenen Textausgabe auf der
Konsole führen.
class Person {
String name;
char geschlecht;
...
...
}
class Student extends Person {
long matrikel;
...
...
Auf der Konsole
Name:
Karmal, Bernd
Geschlecht: m
Name:
Karmal, Bernd
Geschlecht: m
Matrikelnr: 1235566
Name:
Geschlecht:
Matrikelnr:
Semester:
Karmal, Bernd
m
1235566
I6
}
class Semestersprecher extends Student {
String semester;
...
...
}
public class Test {
public static void main(String[] args) {
Person per[] = new Person[3];
per[0] = new Person("Karmal, Bernd", 'm');
per[1] = new Student("Karmal, Bernd", 'm', 1235566);
per[2] = new Semestersprecher(
"Karmal, Bernd", 'm', 1235566, "I6");
for(int i = 0; i < per.length; i++)
System.out.println(per[i] + "\n");
}
}
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
7/11
Termin 3: Tastatur, Maus und Graphik
Aufgabe 1
Schreiben Sie ein Programm zur graphischen Darstellung der Fourier-Reihe der
Rechteck-Funktion (siehe Bild 2.1):
y=
4
π
k
1
∑ 2i − 1 sin( (2i − 1) π x )
i =1
−
Die aktuelle Ordnung n = 2 k − 1 , bis
zu der die Reihe entwickelt wurde,
wird im Fenster angezeigt.
−
Man kann die Summationsgrenze k
in Einser-Schritten über die Tastatur
ändern, z.B. erhöhen (+), bzw.
erniedrigen (-). Die zugehörige
Funktion wird jeweils unmittelbar
ausgegeben.
−
Wenn der Benutzer die Fenstergröße ändert, passt sich die Größe
des Diagramms der Änderung an.
Bild 2.1 Beispiel zur Ausgabe der Fourier-Reihe der
Rechteck-Funktion
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
8/11
Aufgabe 2
Schreiben Sie ein Programm, mit dem man bis zu 10 Rechtecke in einem Fenster ausgeben
kann (Bild 2.2).
Bild 2.2 Bis zu zehn Rechtecke
Dabei sollen folgende Anforderungen realisiert werden:
−
Wenn sich der Mauszeiger außerhalb von Rechtecken auf dem Hintergrund des Fensters
befindet und der Benutzer die linke Maustaste drückt, soll an dieser Stelle ein neues
Rechteck mit zufälliger Höhe und Breite hinzugefügt werden.
−
Wenn sich der Mauszeiger innerhalb von Rechtecken befindet und der Benutzer die linke
Maustaste drückt, sollen diese Rechtecke bei gedrückter linker Maustaste mit dem
Mauszeiger bewegt werden können.
−
Wenn sich der Mauszeiger innerhalb von Rechtecken befindet und der Benutzer die
rechte Maustaste drückt, sollen die betroffenen Rechtecke gelöscht werden.
−
Wenn sich der Mauszeiger innerhalb von Rechtecken befindet, lässt sich über Tastatureingaben für diese Rechtecke die Farbe ändern. Die mögliche Auswahl der Farben kann
aus Bild 2.2 entnommen werden, 'm' = Red, 'b' = Blue, 'w' = White. Bei
Drücken der Taste 'a' sollen alle Rechtecke wieder auf die Farbe Schwarz zurückgesetzt
werden.
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
9/11
Termin 4: Zwei Computerspiele
Aufgabe 1
Programmieren Sie das Ein-Personen-Spiel "Trisentis".
Beim Spielbeginn haben alle Felder die Farbe blau. Ziel
des Spiels ist es, alle Felder gelb zu färben.
Wenn man ein Feld anklickt, wechseln die Nachbarfelder
und nur die Nachbarfelder ihre Farbe, also von blau auf
gelb oder von gelb auf blau. In Bild 3.1 sind z.B. die
Felder A1, E1, B5 und E5 angeklickt worden.
1.
Ihr Programm soll das Ein-Personen-Spiel ermöglichen. Ein Doppelklick auf eines der Spielfelder
stellt dabei den Anfangszustand wieder her.
2.
Zusätzlich wird auf Anforderung des Spielers Bild 3.1 Trisentis
(Drücken der Taste A) eine Animation ausgegeben.
Diese Animation zeigt eine Zugfolge, die von der
Anfangsstellung zum "Sieg", d.h. der gewünschten Endstellung führt. Achten Sie
darauf, dass die laufende Animation nicht durch einen Mausklick gestört werden kann!
(Für die, die nicht selbst eine der möglichen Zugfolgen finden: A1, F1, B2, C2, D2, E2, B3, E3, B4, E4,
B5, C5, D5, E5, A6 und F6.)
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
10/11
Aufgabe 2
Programmieren Sie in dieser Aufgabe ein kleines Computerspiel mit dem Namen
"Redsquare". Ziel ist es, das rote Quadrat anzuklicken und bei gedrückter linker Maustaste
festzuhalten. Das rote Quadrat soll dann solange wie möglich bei gedrückter Maustaste in dem
Spielfeld bewegt werden. Man darf dabei nicht gegen die schwarzen Wände stoßen und auch
nicht von einem der blauen Blöcke (den "Gegnern") getroffen werden. Die Zeit, die man
"überlebt" hat, wird am Ende in einer Messagebox ausgegeben. Die graphische Oberfläche des
Spiels ist in Abbildung 4.1 dargestellt.
Bild 4.1 Darstellung der Oberfläche des Computerspiels Redsquare
Die blauen Rechtecke bewegen sich timergesteuert mit konstanter Geschwindigkeit über das
Spielfeld. Sie werden an der äußeren Begrenzung des Spielfeldes bei Auftreffen nach den
üblichen physikalischen Gesetzen (Einfallswinkel = Ausfallswinkel) reflektiert. Die blauen
Blöcke dringen also in den schwarzen Bereich ein und werden erst an der tatsächlichen
Begrenzung des Spielfeldes (das ist der äußere Rand des schwarzen Bereichs) reflektiert.
Treffen blaue Blöcke aufeinander, so laufen sie einfach durcheinander hindurch.
Praktikum OOP mit Java,
Prof. Dr. Th. Klinker
11/11
Bei der Erstellung des Programms sollte eine Klasse RedSquare und eine Klasse
BlueBlock erstellt werden, die jeweils das rote Quadrat und die blauen Rechtecke
beschreiben. Gegebenenfalls können diese beiden Klassen auch aus einer gemeinsamen
Superklasse Block abgeleitet werden.
Für die Startposition, die Größe und die Richtungsvektoren, die die Richtung beschreiben, in
der sich die blauen Blöcke anfänglich bewegen, kann man folgende Werte wählen:
blueBlock1
blueBlock2
blueBlock3
blueBlock4
=
=
=
=
new
new
new
new
BlueBlock( 70, 70, 61,
BlueBlock(270, 58, 61,
BlueBlock( 70, 323, 31,
BlueBlock(299, 333, 101,
61, 17, 11);
45, -10, 12);
55, 15, -13);
25, -12, -20);
Hierbei ist blueBlock1 der Block links oben, blueBlock2 der Block rechts oben,
blueBlock3 der Block links unten und blueBlock4 der Block rechts unten. Dabei
bezeichnen die ersten beiden Parameter des BlueBlock-Konstruktors x- und y-Koordinate
der linken oberen Ecke des jeweiligen Blocks in der Startposition. Die Parameter drei und vier
bezeichnen Breite und Höhe des jeweiligen Blocks. Die Parameter fünf und sechs schließlich
geben x- und y-Koordinate des Richtungsvektors des jeweiligen Blocks zu Beginn der
Bewegung an.
Für das rote Quadrat kann man folgende Werte wählen:
redSquare = new RedSquare(sizeX/2-20, sizeY/2-20, 41, 41);
Hierbei bezeichnen die ersten beiden Parameter des RedSquare-Konstruktors wieder xund y-Koordinate der Startposition (linke obere Ecke). Die Parameter drei und vier
bezeichnen Breite und Höhe des roten Quadrats. Die Variablen sizeX und sizeY stehen
für die Größe des Spielfeldes. Das rote Quadrat wird also zu Beginn des Spiels in die Mitte
des Spielfeldes gesetzt. Für die Werte von sizeX und sizeY und die Breite des
schwarzen Randes MRG kann man folgende Werte wählen:
sizeX = 450,
sizeY = 450,
MRG = 50;
Alle obigen Werte sind natürlich nur Vorschläge. Man kann und sollte diese Werte, sowie den
Wert des Timers variieren und probieren, bis man optimale Werte erhält. Man muss lediglich
darauf achten, dass die blauen Blöcke bei ihrer Bewegung das gesamte Spielfeld abdecken,
damit sie dem roten Quadrat keine "Ruhezone" lassen, in die es sich zurückziehen kann.
Anmerkung: Dieses Spiel wird als Reaktionstest für Piloten verwendet. Berufspiloten sollen
es angeblich bis 2 Minuten schaffen.
Herunterladen