Übungen Programmierung 2 Harald Wehr 24. Juni 2005 Inhaltsverzeichnis 1 Übungsblätter 1.1 Übungsblatt - 08.04.2005: Einführung und Wiederholung 1.2 Übungsblatt - 15.04.2005: OOP - Klassen und Objekte . 1.3 Übungsblatt - 22.04.2005: OOP - Klassen und Objekte . 1.4 Übungsblatt - 29.04.2005: OOP - Vererbung . . . . . . . 1.5 Übungsblatt - 13.05.2005: OOP und ADT . . . . . . . . 1.6 Übungsblatt - 03.06.2005: ADT / Collection Framework 1.7 Übungsblatt - 17.06.2005: Exceptions . . . . . . . . . . 1.8 Übungsblatt - 24.06.2005: Streams und Dateien . . . . . 1.9 Übungsblatt - 30.06.2005: Wiederholung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4 6 8 10 13 18 20 22 23 2 Lösungen 2.1 Lösungen - 08.04.2005: Einführung und Wiederholung 2.2 Lösungen - 15.04.2005: OOP - Klassen und Objekte . 2.3 Lösungen - 22.04.2005: OOP - Klassen und Objekte . 2.4 Lösungen - 29.04.2005: OOP - Vererbung . . . . . . . 2.5 Lösungen - 13.05.2005: OOP und ADT . . . . . . . . 2.6 Lösungen - 03.06.2005: ADT / Collection Framework . 2.7 Lösungen - 17.06.2005: Exceptions . . . . . . . . . . 2.8 Lösungen - 24.06.2005: Streams und Dateien . . . . . 2.9 Lösungen - 30.06.2005: Wiederholung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 31 33 35 37 43 46 49 51 53 . . . . . . . . . 1 Übungsblätter 1.1 Übungsblatt - 08.04.2005: Einführung und Wiederholung Aufgabe 1 Machen Sie sich mit der Entwicklungsumgebung Eclipse vertraut. Legen Sie dabei testweise mehrere Java-Projekte an. Versuchen Sie von Anfang an eine angemessene Struktur ihrer Projekte einzuhalten: • • • • Quellcode in einem src-Ordner Kompilierte Klassen im Ordner classes bzw. bin Externe Libraries im Ordner lib Dokumentationen in einem Ordner doc Versuchen Sie die von Ihnen angelegte Projektstruktur nachzuvollziehen indem Sie sich das Workspace-Verzeichnis von Eclipse näher ansehen. Aufgabe 2 In Java gibt es eine Klasse java.lang.Math, die wichtige mathematische Funktionen bereitstellt. Möchte man den Sinus einer Zahl berechnen, schreibt man etwa: double g; g = Math.sin( Math.PI ); System.out.println( g ); Die Funktion sin() ist demnach eine Methode auf dem Math-Objekt. • Schreibe ein Programm, welches das Maximum von Sinus(0.1) und Kosinus(0.8) ausgibt. Es sollte doch schon eine max()-Funktion geben, oder? Lösungsvorschlag • Die Variablen a, b, c sind vom Typ long und mit beliebigen Zahlen belegt. Wie bekommt man das Minimum auf dem Bildschirm angezeigt? Lösungsvorschlag Aufgabe 3 Um dem Benutzer eines Programms die Möglichkeit zur Eingabe von Werten zu ermöglichen gibt es verschiedene Möglichkeiten. Prof. Geiger hat Ihnen dazu im letzten Semester Hilfsklassen bereitgestellt, mit denen Eingaben über die Kommandozeile möglich waren. Mit Hilfe der Klasse javax.swing.JOptionPane ist dies auch in grafischer Form möglich: import javax.swing.JOptionPane; public class Hallo { public static void main( String args[] ) { String s = JOptionPane.showInputDialog( "Bitte Zahl eingeben" ); System.exit(0); } } 4 • Geben Sie die Eingabe in einer Anweisung, durch einen Tabulator getrennt, zweimal aus. War die Eingabe also xxx, so soll ausgegeben werden: xxx xxx • Realisieren Sie mit Hilfe des Eingabedialogs ein Quadratzahlprogramm. Die Eingabe soll quadriert ausgegeben werden. Lösungsvorschlag Aufgabe 4 Eine Collatz-Folge (bekannt auch als Syracuse-Problem, Kakutani-Poblem, Hasse-Algorithmus und Ulam-Problem) von Lothar Collatz, 1937 ist definiert durch n -> n/2, falls n gerade ist, n -> 3n+1, falls n ungerade ist. Die Folge ist beendet, wenn 1 erreicht ist. Beginnt man etwa mit n = 7, durchläuft der Algorithmus die folgenden Zahlen: 7 -> 22 -> 11 -> 34 -> 17 -> 52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1 Berechne die Collatz-Folge für den Startwert 27. Lösungsvorschlag Aufgabe 5 Berechnen Sie die Fakultät einer Zahl n sowohl auf „normalem“ als auch rekursivem Wege. Lösungsvorschlag 5 1.2 Übungsblatt - 15.04.2005: OOP - Klassen und Objekte Aufgabe 6 Der folgende Programmausschnitt erzeugt einen Punkt (aus dem Package java.awt) und belegt ihn mit Koordinaten: Point p = new Point(); p.setLocation( 12, 34 ); Überlege, ob es auch noch andere Lösungen gibt, den Punkt p auf die Koordinaten (12, 34) zu setzen bzw. neue Punkte zu erzeugen? Schlage in der API der Klasse java.awt.Point nach. Prüfe die Belegung, indem mit toString() die Werte auf dem Bildschirm gebracht werden. Lösungsvorschlag Aufgabe 7 Erzeuge ein leeres Polygon-Objekt. Die Klasse java.awt.Polygon liegt wie Point im Paket java.awt • Ein Polygon besteht aus Punkten, die mit einer Methode hinzugefügt werden. Wie heißt diese Methode? • Erzeuge ein Dreieck. • Teste anschließend, ob ein gewählter Punkt innerhalb des Dreiecks liegt. • Gehören die Punkte auf der Linie zum Inneren? Was ist mit den Punkten selbst? Gehören sie zum Inneren oder Äußeren des Polygons? Lösungsvorschlag Aufgabe 8 Um grafische Benutzeroberflächen zu erstellen exisitiert im java.awt-Package die Klasse java.awt.Frame • Lege ein Frame-Objekt an. • Man muss eine Methode nutzen, um es auf dem Bildschirm darzustellen. Wie heißt die Methode? Tipp: Vielleicht irgendetwas wie „anzeigen“ auf Englisch? • Wenn man das Programm startet, ist das Fenster ziemlich klein. Wie kann man die Größe des Fensters setzen? • Der Titel eines Fensters kann ebenfalls gesetzt werden. Welche beiden Möglichkeiten gibt es dafür? • Weise dem Fenster einen blauen Hintergrund zu. 6 Lösungsvorschlag Aufgabe 9 Implementiere eine Funktion dist(Point p), die die Distanz zum Nullpunkt als Fließkommazahl zurückgibt. Kurz skizziert soll die Funktion folgendes Format haben: static double dist( Point p ) { // return Abstand zum Nullpunkt } Implementiere eine Funktion abs(Point), die in einem übergebenen Point-Objekt darauf achtet, dass die Koordinaten alle positiv sind. Wenn etwa der Funktion ein Objekt Point p = new Point(-2,2) übergeben wird, dann wird nach dem Aufruf von abs(p) das Point-Objekt die Koordinaten (2,2) beinhalten. Lösungsvorschlag 7 1.3 Übungsblatt - 22.04.2005: OOP - Klassen und Objekte Aufgabe 10 Implementierte eine Klasse Radio mit folgenden Attributen: • eingeschaltet, wenn ein Radio an oder aus ist, • lautstaerke, wie laut spielt das Radio Musik? Welche Typen sind sinnvoll? Schreibe zusätzlich eine Klasse Haus, die ein Radio-Objekt in ihrer main-Funktion aufbaut. Lösungsvorschlag Aufgabe 11 Erweitere die Klasse Radio mit folgenden (nicht statischen) Methoden: lauter() leiser() an() aus() istAn() Einige Methoden sollen dabei die Objektvariable lautstaerke ändern. an()/ aus() sollen Meldungen wie „an“/„aus“ auf dem Bildschirm ausgeben. (Hinweis: Die Lautstärke soll nur im Bereich von 0 bis 100 liegen.) Implementiere zusätzlich folgende Methoden: • waehleSender(double frequenz). Sie soll eine Frequenz intern speichern, wie die Lautstärke. • public String toString(). Sie soll Informationen über den internen Zustand als String zurückgeben, wobei die Zeichenkette die Form „Radio an: Freq=234, Lautstaerke=2“ haben sollte. Innerhalb von Haus sollen nun in der main()-Methode die Objektfunktionen des Radios getestet werden. Damit kommt die Radio-Klasse ohne main()-Methode aus. Sie wird in Haus eingesetzt. Darin soll etwa Folgendes möglich sein: Radio r2 = new Radio(); r2.an(); r2.lauter(); r2.lauter(); System.out.println( r2 ); r2.aus(); Lösungsvorschlag Aufgabe 12 8 Verändere den Zugriffsschutz alle bisher genutzen Variablen, damit diese nur noch innerhalb der Klasse Radio nutzbar sind. Die Schnittstelle nach aussen übernehmen getter- und setter -Methoden. (Tipp: Lass Eclipse die Arbeit übernehmen ;-) ) Füge einen privaten Zustand int band ein, der entweder FM oder AM sein kann. FM und AM sollen Konstanten vom Typ Ganzzahl in der Radio-Klasse sein. Setze das Band über eine Methode setzeBand(band). Lösungsvorschlag 9 1.4 Übungsblatt - 29.04.2005: OOP - Vererbung Aufgabe 13 Gegeben sei die folgende Klasse Fahrzeug: package fahrzeuge; public class Fahrzeug { int raeder; // Anzahl Raeder public Fahrzeug(int raeder) { this.raeder = raeder; } public void print() { System.out.println("Raeder: " + raeder); } } Leiten Sie aus der Klasse Fahrzeug zunächst die Klassen KraftFahrzeug und Fahrrad ab. Die Klasse KraftFahrzeug soll als zusätzliche Attribute den Hubraum (Typ int) und die Leistung (in kW, Typ int) des Kraftfahrzeugs definieren. Die Klasse Fahrrad soll ein zusätzliches Attribut definieren, welches angibt, ob das Fahrrad über Rücktritt verfügt. Leiten Sie schließlich aus der Klasse KraftFahrzeug die Klasse PKW ab. Die Klasse PKW soll als zusätzliches Attribut die Anzahl der Sitzplätze aufweisen. Statten Sie jede der von Ihnen erzeugten Klassen mit einem Konstruktor aus, der als Parameter alle notwendigen Informationen übergeben bekommt, um die jeweiligen Attribute mit sinnvollen Werten zu belegen. Statten Sie weiterhin alle Klassen mit der Methode public void print() aus, welche die Werte der Instanzvariablen ausgeben soll. Sowohl die Konstruktoren als auch die print -Methoden sollen jeweils nur die klassenspezifischen Attribute initialisieren bzw. ausgeben! Die Bearbeitung von ererbten Attributen soll durch die Konstruktoren bzw. Methoden der entsprechenden Oberklasse(n) erfolgen. Lösungsvorschlag Aufgabe 14 Gegeben seien die folgenden Klassen ATest und BTest class ATest { int i = 0; double d; ATest(int i, double d) { //super(); this.i = i; 10 this.d = d; } ATest() { this(11, 22.0); } } public class BTest extends ATest { int i = 0; public BTest() { //super(); i++; d++; } public static void main(String[] args) { BTest b = new BTest(); System.out.println("b.i = " + b.i); System.out.println("b.d = " + b.d); System.out.println("((A) b).i = " + ((ATest) b).i); System.out.println("((A) b).d = " + ((ATest) b).d); } } Welche Werte werden in der main-Methode ausgegeben? Erklären Sie, wie die Werte zustande kommen, indem Sie angeben, in welcher Reihenfolge welche Konstruktoren aufgerufen werden und auf welche Attribute welcher Klassen bei den Ausgaben zugegriffen wird! Lösungsvorschlag Aufgabe 15 Polymorphismus ist eines der wichtigsten, aber auch der am meisten verwirrenden Konzepte beim Erlernen der objektorientierten Programmierung. Zusammen mit abstrakten Klassen ergibt sich ein mächtiges Instrumentarium für eine Vielzahl von Anwendungen. Ihre Aufgabe besteht nun darin, ein Programm gemäß der nachfolgenden Spezifikation zu erstellen: • Schreiben Sie eine abstrakte Klasse Angestellter, die Daten über einen Angestellten enthält. Die Klasse hat die beiden Methoden monatsGehalt und jahresGehalt , die das Gehalt des Angestellten für einen Monat bzw. ein komplettes Jahr ermitteln. monatsGehalt ist abstrakt und wird erst in abgeleiteten Klassen implementiert. Dagegen ist jahresGehalt bereits in der Basisklasse implementiert und realisiert das Jahresgehalt durch Multiplikation des Monatsgehalts mit 12. • Schreiben Sie die abgeleiteten Klassen Manager, Sekretaerin und Verkaeufer und 11 implementieren sie darin die Methode monatsGehalt wie folgt: – Die Sekretärin bekommt ein festes Gehalt je Monat. – Der Verkäufer bekommt ein festes Gehalt und zusätzlich anteilige Verkaufsprovisionen. – Der Manager bekommt ein festes Gehalt und zusätzliche eine Zulage für jede der folgenden Aktivitäten, sofern er sie ausübt: 1. Mitglied der Geschäftsführung. 2. Führungskraft für mehr als 12 Mitarbeiter. 3. Mehr als 10-jährige Firmenzugehörigkeit. • Neben monatsGehalt sollen in den abgeleiteten Klassen Methoden zum Zugriff und zur Abfrage der einzelnen Gehaltsbestandteile zur Verfügung stehen. • Schreiben Sie weiterhin ein Testprogramm, das ein Array von Angestellten unterschiedlichen Typs erzeugt und berechnen Sie das monatliche und jährliche Gehalt für alle Angestellten. Verwenden Sie innerhalb des Testprogramms keine expliziten Verzweigungen, um den Typ des Angestellten herauszufinden, sondern nutzen Sie die Vorteile polymorpher Variablen. Lösungsvorschlag 12 1.5 Übungsblatt - 13.05.2005: OOP und ADT Aufgabe 16 Gegeben sei folgendes Klassendiagramm: Die Interfaces Fax und Drucker sind gegeben durch package hardware; public interface Fax { void senden(String text); } package hardware; public interface Drucker { void drucken(String text); } Des weiteren die Klasse Geraet: package hardware; public class Geraet { protected String geraeteId; } Und die Klasse FaxGeraet: package hardware; public class FaxGeraet extends Geraet implements Fax { static int id = 0; 13 FaxGeraet() { id++; geraeteId = "Fax" + id; } public void senden(String text) { System.out.println("\nAbsender ist: " + geraeteId); System.out.println("\nDas Senden wird simuliert"); System.out.println(text); } } Schreiben Sie die Klasse Laserdrucker und die Klasse Kombigeraet. Implementieren Sie die fehlenden Methoden entsprechend der Implementierung der gegebenen Klasse FaxGeraet. Schreiben Sie eine Main-Methode mit folgendem Inhalt: package hardware; class TestGeraete { public static void main(String[] args) { Laserdrucker l1 = new Laserdrucker(); Laserdrucker l2 = new Laserdrucker(); FaxGeraet f1 = new FaxGeraet(); FaxGeraet f2 = new FaxGeraet(); KombiGeraet k1 = new KombiGeraet(); KombiGeraet k2 = new KombiGeraet(); f1.senden("Dies ist ein Test"); f2.senden("Dies ist ein Test"); l1.drucken("Dies ist ein Test"); l2.drucken("Dies ist ein Test"); k1.senden("Dies ist ein Test"); k2.senden("Dies ist ein Test"); k1.drucken("Dies ist ein Test"); k2.drucken("Dies ist ein Test"); } } Die Ausführung der Main-Methode soll folgendes auf dem Bildschirm ausgeben: Absender ist: Fax1 Das Senden wird simuliert Dies ist ein Test Absender ist: Fax2 Das Senden wird simuliert Dies ist ein Test Drucker Laser1 meldet sich Es wird gedruckt Dies ist ein Test Drucker Laser2 meldet sich Es wird gedruckt Dies ist ein Test Absender ist: Kombigeraet1 Das Senden wird simuliert Dies ist ein Test Absender ist: Kombigeraet2 Das Senden wird simuliert Dies ist ein Test Kombigeraet Kombigeraet1 meldet sich Es wird gedruckt Dies ist ein Test Kombigeraet Kombigeraet2 meldet sich 14 Es wird gedruckt Dies ist ein Test Lösungsvorschlag 15 Aufgabe 17 Verkettete Listen können beliebige Arten von Nutzinformationen speichern. In dieser Aufgabe sollen Sie eine Klasse GeoListe schreiben, die eine verkettete Liste von geometrischen Elementen speichert. Benutzen Sie zur Darstellung der Objekte die Klasse Geo und ihre Unterklassen Kreis und Rechteck. Gegeben sei die Klasse Geo: package geometrie; public class Geo { private int x, y; // x,y-Koordinaten des Bezugspunkts public Geo(int x, int y) { this.x = x; this.y = y; } } Implementieren Sie die Klassen Kreis und Rechteck. Die Klasse Kreis soll neben den Koordinaten des Bezugspunkts ein Attribut double radius definieren. Implementieren Sie einen passend parametrisierten Konstruktor, der alle Attribute mit Werten versorgt. Die Klasse Rechteck soll neben den Koordinaten des Bezugspunkts die Attribute double breite und double hoehe definieren. Implementieren Sie auch hier einen passend parametrisierten Konstruktor, der alle Attribute mit Werten versorgt. Weiterhin sollen beide abgeleiteten Klassen über die folgenden Methoden verfügen: • public void verschieben(int dx, int dy): Verschiebt den Bezugspunkt des Objekts auf der Zeichenfläche horizontal um dx Einheiten und vertikal um dy Einheiten. • public double flaeche(): Gibt den Flächeninhalt des Objekts zurück. Schreiben Sie zunächst eine Klasse GeoListenElement, die ein Listenelement mit einer Nutzinformation vom Typ Geo realisiert. Statten Sie die Klasse GeoListenElement mit einem Konstruktor public GeoListenElement(Geo g) aus, der ein neues Listenelement mit Nutzinformation g erzeugt. Implementieren Sie dann die Klasse public class GeoListe. Diese Klasse soll über ein Attribut verfügen, das auf das Kopfelement der jeweiligen Instanz zeigt. Weiterhin sollen die folgenden Methoden realisiert werden: • Konstruktor public GeoListe(): Erzeugt eine neue (leere) GeoListe. • public void insert(Geo g): Erzeugt ein neues GeoListenElement mit dem geometrischen Objekt g als Nutzinformation und fügt das neue Element am Listenanfang ein. • public double groessteFlaeche(): Gibt die Fläche desjenigen Elements der Liste zurück, das die größte Fläche aller Listenelemente aufweist. • public static void main(String[] args): Erzeugt eine neue Liste und fügt der Reihe nach folgende Elemente ein: 16 – einen Kreis mit Radius 5.5, – ein Rechteck mit Breite 2.0 und Höhe 5.0, – einen Kreis mit Radius 8.3 und – ein Rechteck mit Breite 3.0 und Höhe 6.0. • Schließlich soll mit Hilfe der Methode groessteFlaeche() die Fläche des flächengrößten Listenelements bestimmt und ausgegeben werden. Lösungsvorschlag 17 1.6 Übungsblatt - 03.06.2005: ADT / Collection Framework Aufgabe 18 • Erzeuge eine java.util.ArrayList mit 5 Zufallszahlen zwischen 0-100 (0 und 100 inklusive). • Gib die Elemente mit einem Iterator aus. • Sortiere die Elemente. Nutze dafür aus der Utility-Klasse java.util.Collections eine schlaue Funktion. • Ergänze das Hauptprogramm mit einer statischen Funktion Collection generateRandom (int size, double min, double max). Sie soll eine beliebige Datenstruktur aufbauen und mit size Elementen füllen. Die Zufallszahlen sollen im Bereich von min bis max (beide inklusive) liegen. – Ist es günstig, den Rückgabetyp java.util.Collection zu nehmen, oder sollte man besser etwas anderes nehmen, wenn man auf den Wert der Rückgabe ebenfalls die Methode void Collection.sort(List l) anwenden können soll? Lösungsvorschlag Aufgabe 19 Wir unterscheiden für die Speicherung von Elementen in einer Menge die Klassen java.util .HashSet und java.util.TreeSet. • Erzeuge jeweils ein Objekt vom Typ java.util.HashSet und java.util.TreeSet und füge die Zeichenketten „möchtest“, „du“, „wertvolle“, „dinge“, „sehen“, „so“, „blicke“, „dorthin“, „ , “, „wohin“, „die“, „große“, „menge“, „nicht“, „sieht“. ein. Bei dieser Anzahl von Zeichenketten ist es vielleicht schlau, eine Funktion zu nutzen, die eine Folge von Zeichenketten in ein Set einfügt. Überlege, wie man intelligent die Methoden asList() aus java.util.Arrays und addAll(Collection c) aus java.util .Set nutzen kann. • Gib mit toString() die Elemente aus. Was fällt auf? • Füge den String „so“ ein. Was passiert? • Füge ein Datums-Objekt java.util.Date mit new Date() ein. Was ist die Konsequenz? • Erzeuge zusätzlich noch eine Liste vom Typ Vector und füge die Wörter ein. Wie sieht die Ausgabe hier aus? 18 Lösungsvorschlag Aufgabe 20 Schreibe eine Funktion, die ein zweidimensionales Array bestehend aus String in eine java .util.Map konvertiert. Ein Beispiel: String feld[][] = new String[][] { { "rot", "#FF0000" }, { "grün", "#00FF00" }, { "blau", "#0000FF" } }; Der erste Eintrag des Array soll der Schlüssel, der zweite der Wert in der Map werden. Wie lässt sich der Wert für blau sowohl aus dem Array als auch aus der Map ermitteln? Lösungsvorschlag Aufgabe 21 In einem Lottospiel werden 7 Zahlen aus 49 gezogen. Bilde eine Liste mit 49 Zahlen und ziehe 7. Überlege, wie man die Funktion shuffle() aus java.util.Collections dafür nutzen kann. Lösungsvorschlag Aufgabe 22 Die Funktion sort() aus java.util.Arrays kann nur nach Kriterien sortieren, die sie kennt. Sollen unbekannte Objekte miteinander verglichen werden, so müssen wir dem sort() ein spezielles Objekt mitgeben, welches das Sortierkriterium beachtet. Somit implementiert man eine Klasse, die compare() aus java.util.Comparator implementiert. class MyComparator implements Comparator { // Compares its two arguments for order. int compare( Object o1, Object o2 ) } Schreibe einen Vergleichs-Comparator für java.awt.Point-Objekte. Als Vergleichsmöglichkeit soll die Distanz zum Nullpunkt verwendet werden. Nutze die Objektmethode distance() der java.awt.Point-Klasse. Dann sollen ein paar Punkte in ein Feld eingestellt und sortiert werden. Point points[] = { new Point( 9, 3 ), new Point( 3, 4 ), new Point( 4, 3 ), new Point( 1, 2 ), }; Arrays.sort( points, ... ); Lösungsvorschlag 19 1.7 Übungsblatt - 17.06.2005: Exceptions Aufgabe 23 Gegeben ist die Klasse Fehler, deren beiden Methoden fehler1() und fehler2() Ausnahmen hervorrufen und diese an die aufrufende Methode automatisch weitergeben, da sie die Ausnahmen nicht abfangen. package exceptions; public class Fehler { public static void fehler1() { int ai[] = { 0, 1, 2 }; ai[3] = 4; } public static void fehler2() { int i = 5 / 0; } } Finden Sie heraus, welche Exceptions jeweils von den Methoden hervorgerufen werden. Schreiben Sie eine Klasse FehlerBehandlung, die ein Hauptprogramm besitzt. Dieses Hauptprogramm soll zunächst die Methode fehler1() aufrufen und dabei die Ausnahme abfangen. Als Reaktion auf die Ausnahme soll folgender Hinweis auf dem Bildschirm ausgeben werden: Fehler1: <String des Exceptionobjekts> Danach soll in dem Hauptprogramm die Methode fehler2() aufgerufen und dabei ihre Aus- nahme abgefangen werden. Als Reaktion soll wiederrum folgender Hinweis in einer neuen Zeile auf dem Bildschirm ausgegeben werden: Fehler2: <String des Exceptionobjekts> Lösungsvorschlag Aufgabe 24 Schreiben Sie ein Programm, das ein vorgegebenes Array in einer while-Schleife durchläuft. Anstatt die Länge des Arrays als Abbruchbedingung der Schleife zu verwenden, soll die Schleife solange laufen, bis eine Ausnahme des Typs ArrayIndexOutOfBoundsException erzeugt wird. Hinweis: Diese Aufgabe dient nur zur Übung von Exceptions, die geforderte Lösung sollte niemals tatsächlich zum Durchlaufen von Arrays benutzt werden! Lösungsvorschlag Aufgabe 25 Um in Java den Zugriff auf globale Variablen zu erhalten, dies aber trotzdem „halbwegs“ objektorientiert hinzubekommen, existiert das Enturfsmuster des Singleton. Von dieser Klasse soll nur ein einziges Objekt geschaffen werden können. Schreiben Sie eine solche Klasse Singleton. Der Konstruktor der Klasse Singleton soll public sein. Wird versucht, ein zweites Objekt der Klasse zu erzeugen, so soll eine Exception der Klasse SingletonException geworfen 20 werden. Die Klasse soll sich natürlich ihre einzige Instanz merken können und bei Aufruf der (statischen) Methode getInstanz() diese zurückgeben. Gegeben Sei folgende Klasse zum Testen der Aufgabe: package exceptions; class TestSingleton { static public void main(String[] args) { Singleton ref1; Singleton ref2; try { //Erzeugen eines Singletons ref1 = new Singleton(); //Erzeugen des zweiten Singletons versucht ref2 = new Singleton(); System.out.println("2 Singletons erzeugt"); } catch (SingletonException e) { System.out.println(e.getMessage()); } finally { System.out.println("Ende der Aufgabe"); } } } Lösungsvorschlag 21 1.8 Übungsblatt - 24.06.2005: Streams und Dateien Aufgabe 26 Schreibe mit Hilfe der Klasse java.io.File und der Methode listFiles() ein Programm, welches den Verzeichnisinhalt für c:\ (unter Linux /) auflistet. Jedes Verzeichnis soll in eckige Klammern gesetzt werden, also etwa [winnt]. Trenne die Ausgaben, sodass erst die Verzeichnisse, dann die Dateien ausgegeben werden. Die Namen sollen jeweils sortiert ausgegeben werden. Lösungsvorschlag Aufgabe 27 Implementiere eine Methode String findFile(String path, String filename), die das Verzeichnissystem unter path nach filename rekursiv durchsucht und jeden Treffer ausgibt. Lösungsvorschlag Aufgabe 28 Die Datei namen.txt (im Linux-Labor unter /usr/local/wehr/programmierung2/namen .txt) enthält Familiennamen. Speichere die Datei auf dem eigenen Dateisystem. Lies die Datei mit der readLine()-Methode aus java.io.RandomAccessFile ein und gib die Zeilen folgendermaßen aus: • Die Namen sollen zunächst der Länge nach sortiert werden, also erst alle Namen der Länge 2, dann 3 usw. • Innerhalb dieser Blöcke sollen die Namen entsprechend ihrer Buchstaben lexikographisch sortiert werden. Lösungsvorschlag Aufgabe 29 Lege eine neue Datei auf der Festplatte an und schreibe deinen Namen in diese Datei. Wenn die Datei schon existiert, soll der Name an das Ende der Datei angehängt werden. Lösungsvorschlag 22 1.9 Übungsblatt - 30.06.2005: Wiederholung Aufgabe 30 Kennzeichnen Sie die nachfolgenden Aussagen als wahr oder falsch. Begründen Sie kurz Ihre Auswahl! w f Die Ausführung der main-Methode erfolgt über einen polymorphen Aufruf. w f Es gibt keine Klassen ohne Konstruktor. w f Eine Klasse hat entweder nur static-Methoden oder keine static-Methoden. w f Java-Objekte können das Ende des Blocks, in dem sie erzeugt wurden, überleben. Lösungsvorschlag Aufgabe 31 Kennzeichnen Sie die nachfolgenden Aussagen als wahr oder falsch ohne Begründung! w f Instanzen werden in Java bei der Deklaration der Instanznamensvariablen erzeugt. w f Die spezielle Variable this beinhaltet immer die Referenz auf die aktuelle Instanz. w f Klassenvariablen werden mit dem Schlüsselwort protected deklariert. w f Konstuktoren können in Java genau so wie andere Methoden überladen werden. w f Jede Instanz besitzt eigene Werte für die Instanzvariablen. w f Durch das Schlüsselwort new wird der Konstruktor einer Klasse aufgerufen. w f Mit dem Modifikator protected versehene Java-Methoden sind nur in der Klasse verwendbar, in der sie definiert wurden. w f Java unterstützt Mehrfachvererbung durch das Schlüsselwort extends w f Eine Instanzmethode darf in ihrem Rumpf andere Klassenelemente verwenden. w f Eine Klassenmethode darf in ihrem Rumpf nicht das Schlüsselwort this verwenden. w f Eine Klassenvariable muss in einer Methode initialisiert werden. w f Ein Interface kann mittels implements mehrere andere Interfaces implementieren. 23 w f Beim Überschreiben einer Methode müssen deren Zugriffsrechte berücksichtigt werden. w f Ein abstrakt deklarierter Konstruktor ergibt keinen Sinn. w f javac erzeugt plattformunabhängigen Bytecode. w f Klassen können in Java höchstens eine direkte Superklasse besitzen. w f Instanzmethoden können public static deklariert werden. w f Die Klasse Object ist in Java Subklasse jeder anderen Klasse. w f Symbolische Konstanten werden mit private deklariert. Lösungsvorschlag Aufgabe 32 Erkenne den Fehler in den jeweiligen Programmen: 1. class Hallo { public static ausgeben() { System.out.println("Hallo!!"); } public static void main( String[] args) { ausgeben(); } } 2. class X { private int x; } class Y { private int y; private X x; Y() { this.x = new X(); this.x.x = y; } } 24 3. interface I { public abstract void f(); } abstract class A implements I { public abstract void f(int x); } class C extends A { public void f(int x) { } } 4. int[] xs = { 1, 2, 3, 4, 5 }; for(int x= 1; x <= 5; x++) { System.out.println(xs[x]); } Lösungsvorschlag Aufgabe 33 Gegeben sei der folgende Programmcode: package demo; public class A { int zahl = 5; public A(int z) { zahl=z; } public static void print(String s) { System.out.println("Ausdruck: "+s); } public void print() { System.out.println(zahl); } } Beschreiben Sie kurz was die nachfolgenden Programme jeweils tun, bzw. welche Fehler ggf. aufreten: 1. package demo; public class B1 { public static void main(String[] args) { A.print(); 25 } } 2. package demo; public class B2{ public static void main(String[] args) { A a = new A(); a.print(); } } 3. package demo; public class B3{ public static void main(String[] args) { A a = new A(35); a.print(); } } 4. package demo; public class B4 extends A{ public B4() { super(0); } public static void main(String[] args) { print("Test"); } } 5. package demo; public class B5 extends A{ public B5() { super(10); } public void print() { System.out.println(zahl+10); } public static void main(String[] args) { B5 b = new B5(); b.print(); 26 A a = new B5(); a.print(); } } Lösungsvorschlag Aufgabe 34 Implementiere eine Klasse Kreis und Rechteck mit den Eigenschaften x, y und für Rechteck höhe, breite und für Kreis radius vom Typ double. Implementiere für beide Klassen eine Methode double flaeche(). Überschreibe die Methode toString() von Object, so dass die Klassen sinnvolle Zeichenketten zurückgeben. Leite die Objekte von einer Oberklasse Form ab. Mache die Oberklasse abstrakt und flaeche () ebenso. Implementiere eine Klasse FormContainer, die eine void add(Form f)-Methode besitzt. Mit ihr soll man beliebige Form-Objekte im Container ablegen können. Intern soll der Container sich die Elemente in einem Feld vom Typ Form halten. Schreibe eine Methode double gesamtFlaeche() im Container, die über alle Formen summiert und die Gesamtfläche zurückgibt. Lösungsvorschlag Aufgabe 35 Die Klasse KonstruktorenReihenfolge soll zum Test der Reihenfolge von Konstruktoraufrufen bei abgeleiteten Klassen dienen: package konstruktoren; public class KonstruktorenReihenfolge { public static void main(String[] args) { System.out.println("Exemplar von A wird angelegt"); A aRef = new A(); System.out.println(); System.out.println("Exemplar von B wird angelegt"); B bRef = new B(); System.out.println(); System.out.println("Exemplar von C wird angelegt"); C cRef = new C(); System.out.println(); } } Schreiben Sie 3 Klassen A, B und C, welche jeweils nur einen Konstruktor ohne Parameter enthalten. Im Konstruktor der Klasse A soll ausgegeben werden: System.out.println("Klasse A - Konstruktor ohne Parameter"); Entsprechendes gilt für die Klassen B und C. Beachten Sie, dass B von A und C von B abgeleitet sein soll. Können Sie die Ausgabe erklären? Lösungsvorschlag Aufgabe 36 27 Schreiben Sie eine Klasse Alpha. Die Zahl der erzeugten Objekte von Alpha soll im Konstruktor hochgezählt werden. Im Konstruktor soll der folgende Text ausgegeben werden: Objekt x erzeugt x soll dabei die Nummer des jeweiligen Objektes sein. Damit in Java der Garbage Collector Objekte löschen kann, dürfen diese nicht mehr referenziert werden, sprich: keine Variable darf mehr auf das Objekt verweisen. Machen Sie das Entfernen von Objekten sichtbar, in dem sie die finalize-Methode der Klasse java.lang.Object in Alpha überschreiben. Erzeugen Sie soviel (unreferenzierte) Instanzen von Alpha damit die Garbage Collection sichtbar wird. Lösungsvorschlag Aufgabe 37 Schreiben Sie für die Klasse MeinPunkt: • einen Konstruktor ohne Parameter, der die Koordinaten auf x = 0 und y = 0 initialisiert, • einen Konstruktor mit einem Parameter, der den x-Wert des Punktes mit dem übergebenen Wert initialisiert und die y-Komponente auf 0 setzt, • einen Konstruktor mit 2 Parametern, der beide Attribute des Punktes setzt. Schreiben Sie eine Testklasse die 3 Punkte erzeugt. Der erste Punkt soll mit dem Konstruktor ohne Parameter, der 2. Punkt mit dem Konstruktor mit 1 Parameter und der 3. Punkt mit dem Konstruktor mit 2 Parametern initialisiert werden. Anschließend sind die Koordinaten aller 3 Punkte auszugeben. Lösungsvorschlag Aufgabe 38 Gegeben ist die Spezifikation der Datenbehälterklasse Anschluss, um Telefonanrufe zu verwalten: public class Anschluss { private boolean belegt; private int einheiten; public public public public void anrufen() throws BelegtAusnahme {}; void auflegen() {}; boolean istBelegt() {}; int getEinheiten() {}; } Implementieren Sie die Klasse Anschluss. Schreiben Sie weiterhin eine Klasse ISDNAnschluss mit denselben vier Methoden, die aber zwei Anschluss-Objekte besitzt. Ein ISDN-Anschluss meldet dann „belegt“, wenn beide Leitungen belegt sind; daher können Sie anrufen, wenn eine der Leitungen frei ist. Die Anzahl der vertelefonierten Einheiten eines ISDN-Anschlusses ist die Summe der Einheiten der einzelnen Anschlüsse. Lösungsvorschlag 28 Aufgabe 39 Gegeben sei das UML-Klassendiagramm einer Klasse Hochhaus. Setzen Sie die Klasse in Java um. Beachten Sie dabei folgende Hinweise: • Die Bauzeit beträgt pauschal 20 Tage für das Fundament, plus 5 Tage je Etage. • Ab 5 Stockwerken wird ein Fahrstuhl erforderlich. Ab 30 m Gebäudehöhe wird ein zweiter Fahrstuhl nötig, ab 50 m ein dritter. • Die nutzbare Wohnfläche der obersten Etage entspricht 95% der Etagen-Grundfläche. Jede weitere Etage besitzt eine um 5 Prozent verringerte Wohnfläche gegenüber der nächsthöheren Etage (für Versorgungsleitungen, Stützen, etc.) • Die Baukosten betragen 200.000 EUR für Planung, Baustelleneinrichtung, etc., plus 450 EUR pro m2 Grundfläche je Etage. Jeder Fahrstuhl kostet weitere 70.000 EUR. • Der Gewinn berechnet sich aus Differenz zwischen Baukosten, jährlichen Kosten und Mieteinnahmen. Die jährlichen Kosten können zu 5% der Baukosten angenommen werden. Die Miete beträgt jährlich 60 EUR/m2 Wohnfläche (Annahme: 100% Auslastung). • Schreiben Sie eine Test-Klasse, die ein Hochhaus mit 10 Stockwerken a 3.80 m und einer Grundfläche von 32,0 x 18,0 m erzeugt. Lassen Sie sich die Bauzeit, die Gesamtwohnfläche und den jährlichen Gewinn für die ersten 20 Jahre ausgeben. Lösungsvorschlag 29 2 Lösungen 2.1 Lösungen - 08.04.2005: Einführung und Wiederholung Lösung zu Aufgabe 2 • Maximum.java public class Maximum { public static void main(String args[]) { double g; double h; g = Math.sin(0.1); h = Math.cos(0.8); System.out.println("Wert von g: " + g); System.out.println("Wert von h: " + h); System.out.println("Maximum: " + Math.max(g, h)); } } • Minimum.java public class Minimum { public static void main(String args[]) { long a = 2; long b = 3567; long c = 21; System.out.println("Minimum: " + Math.min(Math.min(a, b), c)); } } Lösung zu Aufgabe 3 import javax.swing.JOptionPane; public class JOptionEingabe { public static void main(String args[]) { String s = JOptionPane.showInputDialog("Bitte Zahl eingeben"); System.out.println(s + "\t" + s); int x = Integer.parseInt(s); System.out.println(x * x); // oder für x * x auch // Math.pow( x, 2 ); System.exit(0); } } Lösung zu Aufgabe 4 class CollatzFolge { public static void main(String args[]) { int n = 27; System.out.print(n + " -> "); while (n > 1) { if (n % 2 == 0) n /= 2; else n = 3 * n + 1; System.out.print(n + " -> "); } System.out.println(); } } 31 Lösung zu Aufgabe 5 import HS_Packages.Read; public class Fakultaet { public static void main(String[] args) { System.out.print("n: "); int n = Read.INT(); System.out.println("n! = " + fakultaet(n)); System.out.println("n! = " + fakultaetRekursiv(n)); } private static long fakultaet(int n) { long fakultaet = 1; int faktor = 1; while (faktor <= n) { fakultaet = fakultaet * faktor++; } return fakultaet; } private static long fakultaetRekursiv(int n) { if (n == 0 || n == 1) return 1; else return n * fakultaetRekursiv(n - 1); } } 32 2.2 Lösungen - 15.04.2005: OOP - Klassen und Objekte Lösung zu Aufgabe 6 import java.awt.Point; public class Punkte { public static void main(String args[]) { // Lösung 1 Point p = new Point(); p.setLocation(12, 34); // Lösung 2 p.x = 12; p.y = 34; // Lösung 3 p.move(12, 34); // Lösung 4 Point q = new Point(); q.translate(12, 34); // Lösung 5 Point r = new Point(); r.setLocation(p); // Lösung 6 Point s = new Point(12, 34); // Lösung 7 Point t = new Point(p); System.out.println(p.toString()); System.out.println(q.toString()); System.out.println(r.toString()); System.out.println(s.toString()); } } Lösung zu Aufgabe 7 import java.awt.Polygon; public class Poly { public static void main(String args[]) { Polygon p = new Polygon(); p.addPoint(2, 6); p.addPoint(5, 2); p.addPoint(8, 6); System.out.println("Beliebiger Punkt: " +p.contains(5, 4)); System.out.println("Endpunkt einer Linie: "+p.contains(2,6)); System.out.println("Punkt auf einer Linie: " +p.contains(5, 6)); } } Lösung zu Aufgabe 8 import java.awt.Color; import java.awt.Frame; public class FensterAWT { public static void main(String args[]) { String title = "Mein erstes Fenster"; Frame fenster1 = new Frame(title); Color blau = new Color(12, 0, 200); 33 fenster1.setBackground(blau); fenster1.setSize(400, 400); fenster1.show(); System.out.println(fenster1.getBackground()); } } Lösung zu Aufgabe 9 import java.awt.Point; public class Distanz { static double dist(Point p) { return Math.sqrt(p.x * p.x + p.y * p.y); } static void abs(Point p) { p.x = Math.abs(p.x); p.y = Math.abs(p.y); } public static void main(String args[]) { Point punkt = new Point(5, 5); System.out.println("x-Koordinate: " + punkt.x); System.out.println("y-Koordinate: " + punkt.y); System.out.println("Abstand vom Koordinatenursprung: " + dist(punkt)); Point p = new Point(-2, 2); System.out.println(p.toString()); // -2,2 abs(p); System.out.println(p.toString()); // 2,2 } } 34 2.3 Lösungen - 22.04.2005: OOP - Klassen und Objekte Lösung zu Aufgabe 10 public class Radio { int lautstärke = 0; boolean eingeschaltet = false; } public class Haus { public static void main(String args[]) { Radio r = new Radio(); r.eingeschaltet = true; r.lautstärke = 12; System.out.println("So laut: " + r.lautstärke); } } Lösung zu Aufgabe 11 public class Radio { int lautstaerke = 0; double frequenz = 0.0; boolean eingeschaltet = false; void waehleSender(double newFrequenz) { if (eingeschaltet) frequenz = newFrequenz; } void volume(int x) { if (eingeschaltet) { lautstaerke += x; if (lautstaerke > 100) lautstaerke = 100; if (lautstaerke < 0) lautstaerke = 0; } } void lauter() { volume(1); } void leiser() { volume(-1); } void an() { eingeschaltet = true; } void aus() { eingeschaltet = false; } boolean istAn() { return eingeschaltet; } public String toString() { return "Radio "+(eingeschaltet ? "an":"aus")+": Sender = " + frequenz + " Lautstaerke = " + lautstaerke; } } Lösung zu Aufgabe 12 public class Radio { public static final int FM = 1; 35 public static final int AM = 0; private private private private int lautstaerke = 0; double frequenz = 0.0; boolean eingeschaltet = false; int band = FM; public void setzeBand(int band) { if ((band == FM) || (band == AM)) this.band = band; else System.out.println("Falsches Band !"); } public int getBand() { return band; } void waehleSender(double newFrequenz) { if (eingeschaltet) frequenz = newFrequenz; } public boolean isEingeschaltet() { return eingeschaltet; } public void setEingeschaltet(boolean eingeschaltet) { this.eingeschaltet = eingeschaltet; } public double getFrequenz() { return frequenz; } public void setFrequenz(double frequenz) { this.frequenz = frequenz; } public int getLautstaerke() { return lautstaerke; } public void setLautstaerke(int lautstaerke) { this.lautstaerke = lautstaerke; } public void setBand(int band) { this.band = band; } private void volume(int x) { if (eingeschaltet) { lautstaerke += x; if (lautstaerke > 100) lautstaerke = 100; if (lautstaerke < 0) lautstaerke = 0; } } void lauter() { volume(1); } void leiser() { volume(-1); } void an() { eingeschaltet = true; } void aus() { eingeschaltet = false; } boolean istAn() { return eingeschaltet; } public String toString() { return "Radio " + (eingeschaltet ? "an" : "aus") + ": Sender = " + frequenz + ", Lautstaerke = " + lautstaerke; } } 36 2.4 Lösungen - 29.04.2005: OOP - Vererbung Lösung zu Aufgabe 13 package fahrzeuge; class Fahrrad extends Fahrzeug { boolean hatRuecktritt; // Hat das Fahrrad Rücktritt? // (ja/nein) // Konstruktor public Fahrrad(boolean hatRuecktritt) { super(2); // Ein Fahrrad hat immer 2 Raeder this.hatRuecktritt = hatRuecktritt; } // Überscheiben der print-Methode von Fahrzeug public void print() { super.print(); // Anzahl Räder ausgeben System.out.println("Rücktritt: " + hatRuecktritt); } } package fahrzeuge; class KraftFahrzeug extends Fahrzeug { int hubraum; // Groeße des Hubraums in ccm int kW; // Motorleistung in kW public KraftFahrzeug(int raeder, int hubraum, int kW) { super(raeder); // Anzahl Raeder setzt der Konstruktor von // Fahrzeug this.hubraum = hubraum; this.kW = kW; } // Überscheiben der print-Methode von Fahrzeug public void print() { super.print(); // Anzahl Raeder ausgeben System.out.println("Hubraum: " + hubraum + "ccm"); System.out.println("Leistung: " + kW + "kW"); } } package fahrzeuge; class PKW extends KraftFahrzeug { int sitzplaetze; // Anzahl der Sitzplaetze des PKW public PKW(int hubraum, int kW, int sitzplaetze) { super(4, hubraum, kW); // Ein PKW hat immer 4 // Räder... this.sitzplaetze = sitzplaetze; // ... aber // variable // Sitzplatzanzahl } // Ueberscheiben der print-Methode von KraftFahrzeug public void print() { super.print(); // Raederanzahl, Hubraum und Leistung ausgeben System.out.println("Sitzplaetze: " + sitzplaetze); } } Lösung zu Aufgabe 14 Ein Blick auf die Klassendefinitionen zeigt, dass sowohl die Klasse ATest als auch die daraus abgeleitete Klasse BTest ein Attribut i deklarieren (Zeilen 2 und 16). Die Deklaration in BTest 37 verdeckt dabei das i der Klasse ATest, so dass Zugriffe auf i in BTest sich immer auf das Attribut der Klasse BTest beziehen. Das Attribut d hingegen wird in BTest nicht überschrieben, so dass es in ATest und BTest gleichermaßen sichtbar ist. Instanzen der Klasse BTest verfügen insgesamt also über drei Instanzvariablen, von denen eine wegen der Verdeckung nicht direkt zugreifbar ist. Die Anweisung new BTest() am Anfang der main-Methode bewirkt die Instanziierung eines Objekts der Klasse BTest, womit gleichzeitig die drei Instanzvariablen erzeugt werden. Java versieht diese initial mit Nullwerten: A i 0 d 0.0 B i 0 Da im vorliegenden Programm Wertzuweisungen an die Variablen ausschließlich in den Konstruktoren stattfinden, ist es notwendig, die Abfolge der Konstruktoraufrufe zu analysieren, um zu verstehen, wie die Wertebelegungen der einzelnen Instanzvariablen zustande kommen. Wie bereits bekannt, werden Konstruktoren immer dann (und nur dann) aufgerufen, wenn Objekte instanziiert werden. Dies geschieht im vorliegenden Programm nur an der oben bereits angesprochenen Stelle, nämlich in der ersten Zeile der main-Methode bei der Erzeugung des Objekts b durch new BTest(). Der Ausdruck new BTest() zieht die folgende Kette von Konstruktoraufrufen nach sich: 1. BTest() Der Konstruktor BTest() enthält als erste Anweisung weder einen expliziten Aufruf eines Konstruktors der Oberklasse (super(...)) noch einen Aufruf eines anderen Konstruktors der Klasse BTest (this(...)). Daher fügt der Compiler hier implizit einen Aufruf des parameterlosen Konstruktors der Oberklasse ein ( super()). Der Aufruf ist in dem Programmlisting als Kommentar eingefügt. Dies führt zum Aufruf von 2. ATest() Die erste (und einzige) Anweisung des Konstruktors ATest() besteht in dem Aufruf eines weiteren Konstruktors der Klasse A. Daher unterbleibt hier die Einfügung eines super()-Aufrufs durch den Compiler. Die Anweisung this(11, 22.0) führt zum Aufruf von 3. ATest(int i, double d) mit i = 11 und d = 22.0 Dieser Konstruktoraufruf führt dazu, dass die Instanzvariablen i und d der Klasse ATest (!) mit den Werten 11 bzw. 22.0 belegt werden. (Auch hier fügt der Compiler - wie im Listing per Kommentar angedeutet - implizit einen Aufruf des Konstruktors der Oberklasse ein, was jedoch für die Analyse der Variablenwerte nicht von Bedeutung ist.) Es ergibt sich folgender Zustand: A i 11 d 22.0 B i 0 38 Nach Beendigung der Ausführung des Konstruktors ATest(int i, double d) kehrt die Kontrolle in den Konstruktor ATest() hinter die Anweisung this(11, 22.0) zurück. Da keine weiteren Anweisungen folgen, ist auch das Ende dieses Konstruktors erreicht, so dass ein weiterer Rücksprung in den Konstruktor BTest() erfolgt, wo die Ausführung hinter dem implizit eingefügten Aufruf super() fortfährt. Die folgende Anweisung i++ wirkt hier auf die Instanzvariable i der Klasse BTest (Verdeckung!). Diese Instanzvariable, die bei ihrer Erzeugung den Default-Wert 0 bekommen hatte, wird nun durch die Inkrementierungsanweisung auf den Wert 1 gesetzt: A i 11 d 22.0 B i 1 Die Anweisung d++ bewirkt hingegen die Erhöhung der Instanzvariablen d der Klasse ATest, da BTest selbst keine gleichnamige Variable deklariert, so dass die Variable d aus ATest geerbt wird. Im Gegensatz zur Variablen i, von der zwei Ausfertigungen existieren (eine in ATest und eine in BTest), gibt es nur eine einzige Variable d, die in der Klasse ATest angesiedelt ist, aber auf Grund der Vererbung auch in BTest sichtbar ist. Folglich greifen sowohl die Methoden der Klasse ATest als auch die der Klasse BTest auf dieselbe Variable d zu. Die Ausführung von d++ führt also zu: A i 11 d 23.0 B i 1 Nun ist das Ende des Konstruktors BTest() erreicht und die Ausführung fährt in der mainMethode in Zeile. Entsprechend der letzten Abbildung der Variablenzustände ergeben sich die folgenden Ausgaben: b.i = 1 b.d = 23.0 Bei den folgenden beiden Ausgaben wird zunächst der Cast-Operator ( ATest) auf b angewandt. Dies weist den Compiler an, das Objekt b als ein Objekt der Klasse ATest zu betrachten, was dazu führt, dass der Compiler etwaige Instanzvariablen nur in der Klasse ATest und deren Oberklassen sucht. Die Klasse BTest wird ausgeblendet. Die beiden Ausgaben greifen hier also auf die Instanzvariablen i und d der Klasse ATest zu: ((A) b).i = 11 ((A) b).d = 23.0 Lösung zu Aufgabe 15 39 • Die Klasse Lohnverwaltung mit main-Methode package lohnverwaltung; public class Lohnverwaltung { public static void main(String args[]) { Angestellter gehaltsliste[] = createGehaltsliste(); showGehaltsliste(gehaltsliste); } static Angestellter[] createGehaltsliste() { Angestellter liste[] = new Angestellter[5]; //Drei Sekretärinnen erzeugen Sekretaerin sek = new Sekretaerin(); sek.setName("Meier, Luise"); sek.setFestgehalt(3200); liste[0] = sek; sek = new Sekretaerin(); sek.setName("Schneider, Paula"); sek.setFestgehalt(2850); liste[1] = sek; sek = new Sekretaerin(); sek.setName("Rabensee, Fridolin"); sek.setFestgehalt(3150); liste[2] = sek; //Einen Verkäufer erzeugen Verkaeufer verk = new Verkaeufer(); verk.setName("Roericht, Eckhart"); verk.setFestgehalt(2000); verk.setProvision(5.0); verk.setUmsatz(85428.73); liste[3] = verk; //Den Geschäftsführer unseres Unternehmens erzeugen Manager man = new Manager(); man.setName("Lottemann, Erwin"); man.setFestgehalt(5500); man.setGeschaeftsfuehrung(true); man.setFuehrungskraft(false); man.setFirmenZugehoerigkeit(true); liste[4] = man; return liste; } static void showGehaltsliste(Angestellter liste[]) { for (int i = 0; i < liste.length; ++i) { System.out.println(liste[i].getName()); System.out.println(" Monatsgehalt: " + liste[i].monatsGehalt()); System.out.println(" Jahresgehalt: " + liste[i].jahresGehalt()); } } } • Angestellter package lohnverwaltung; abstract class Angestellter { private String name; private double festgehalt; public abstract double monatsGehalt(); public double jahresGehalt() { return 12.0 * monatsGehalt(); } public double getFestgehalt() { return festgehalt; } public void setFestgehalt(double festgehalt) { this.festgehalt = festgehalt; } public String getName() { return name; } public void setName(String name) { this.name = name; } } • Sekretaerin 40 package lohnverwaltung; class Sekretaerin extends Angestellter { public double monatsGehalt() { return getFestgehalt(); } } • Verkaeufer package lohnverwaltung; class Verkaeufer extends Angestellter { private double provision; private double umsatz; public double monatsGehalt() { return getFestgehalt() + (provision * umsatz / 100.0); } public double getProvision() { return provision; } public void setProvision(double provision) { this.provision = provision; } public double getUmsatz() { return umsatz; } public void setUmsatz(double umsatz) { this.umsatz = umsatz; } } • Manager package lohnverwaltung; class Manager extends Angestellter { private boolean geschaeftsfuehrung; private boolean fuehrungskraft; private boolean firmenZugehoerigkeit; public double monatsGehalt() { double ret = getFestgehalt(); if (geschaeftsfuehrung) { ret += 1200.0; } if (fuehrungskraft) { ret += 650.0; } if (firmenZugehoerigkeit) { ret += 300.0; } return ret; } public boolean isFirmenZugehoerigkeit() { return firmenZugehoerigkeit; } public void setFirmenZugehoerigkeit(boolean firmenZugehoerigkeit) { this.firmenZugehoerigkeit = firmenZugehoerigkeit; } public boolean isFuehrungskraft() { return fuehrungskraft; } public void setFuehrungskraft(boolean fuehrungskraft) { this.fuehrungskraft = fuehrungskraft; } public boolean isGeschaeftsfuehrung() { return geschaeftsfuehrung; } 41 public void setGeschaeftsfuehrung(boolean geschaeftsfuehrung) { this.geschaeftsfuehrung = geschaeftsfuehrung; } } 42 2.5 Lösungen - 13.05.2005: OOP und ADT Lösung zu Aufgabe 16 • KombiGeraet.java package hardware; public class KombiGeraet extends Geraet implements Drucker, Fax { static int id = 0; KombiGeraet() { id++; geraeteId = "Kombigeraet" + id; } public void drucken(String text) { System.out.println("\nKombigeraet " + geraeteId + " meldet sich"); System.out.println("\nEs wird gedruckt"); System.out.println(text); } public void senden(String text) { System.out.println("\nAbsender ist: " + geraeteId); System.out.println("\nDas Senden wird simuliert"); System.out.println(text); } } • Laserdrucker.java package hardware; public class Laserdrucker extends Geraet implements Drucker { static int id = 0; Laserdrucker() { id++; geraeteId = "Laser" + id; } public void drucken(String text) { System.out.println("\nDrucker " + geraeteId + " meldet sich"); System.out.println("\nEs wird gedruckt"); System.out.println(text); } } Lösung zu Aufgabe 17 • Geo.java package geometrie; public abstract class Geo { private int x, y; // x,y-Koordinaten des Bezugspunkts public Geo(int x, int y) { this.x = x; this.y = y; } public abstract double flaeche(); // -- Verschieben des Bezugspunkts public void verschiebe(int dx, int dy) { 43 x += dx; y += dy; } } • Kreis.java package geometrie; //-- Klasse Kreis, abgeleitet von Geo public class Kreis extends Geo { double radius; // Radius des Kreises //-- Konstruktor public Kreis(int x, int y, double radius) { super(x, y); // Konstruktor von Geo: Bezugspunkt setzen this.radius = radius; // Radius speichern } //-- Flaeche des Kreises berechnen public double flaeche() { return Math.PI * radius * radius; } } • Rechteck.java package geometrie; //-- Klasse Rechteck, abgeleitet von Geo public class Rechteck extends Geo { double breite; // Breite des Rechtecks double hoehe; // Hoehe des Rechtecks // -- Konstruktor public Rechteck(int x, int y, double breite, double hoehe) { super(x, y); // Konstruktor von Geo: Bezugspunkt setzen this.breite = breite; // Breite speichern this.hoehe = hoehe; // Hoehe speichern } // -- Flaeche des Rechtecks berechnen public double flaeche() { return breite * hoehe; } } • GeoListenElement package geometrie; class GeoListenElement { Geo g; // Nutzinformation GeoListenElement next; // Zeiger auf nächstes Listenelement GeoListenElement(Geo g) { this.g = g; } } • GeoListe package geometrie; public class GeoListe { private GeoListenElement kopf; // Neue (leere) Liste erzeugen public GeoListe() { kopf = null; } // Einfügen eines neuen Elements am Listenanfang 44 public void insert(Geo geo) { GeoListenElement neuesElement = new GeoListenElement(geo); neuesElement.next = kopf; kopf = neuesElement; } // Flächengrößtes Element der Liste bestimmen und dessen Fläche zurückgeben public double groessteFlaeche() { double groessteFlaeche = 0.0; // Größte gefundene Fläche for (GeoListenElement le = kopf; le != null; le = le.next) { double flaeche = le.g.flaeche(); // Fläche des atuellen Elements if (flaeche > groessteFlaeche) { // Größer als groessteFlaeche? groessteFlaeche = flaeche; // ... dann merken } } return groessteFlaeche; // Größte gefundene Fläche zurückgeben } // main-Methode zum Testen public static void main(String[] args) { GeoListe l = new GeoListe(); l.insert(new Kreis(10, 20, 5.5)); l.insert(new Rechteck(30, 40, 2.0, 5.0)); l.insert(new Kreis(50, 60, 8.3)); l.insert(new Rechteck(70, 80, 3.0, 6.0)); System.out.println("Groesste Flaeche = " + l.groessteFlaeche()); } } 45 2.6 Lösungen - 03.06.2005: ADT / Collection Framework Lösung zu Aufgabe 18 package collections; import import import import import import import java.util.ArrayList; java.util.Collection; java.util.Collections; java.util.Iterator; java.util.List; java.util.Random; java.util.Vector; public class Zufallszahl { /* wenn der Rueckgabewert mit Collections.sort sortierbar sein muss, sollte java.util.List angewendet werden*/ public static Collection generateRandom(int size, int min, int max) { Random r = new Random(); Collection coll = new Vector(); for (int i = 1; i <= size; i++) { int spanne = max -min + 1; int zufall = (int)(min + spanne*r.nextDouble()); coll.add(new Integer(zufall)); } return coll; } public static void gibAus(Collection c) { Iterator it = c.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } public static void main(String[] args) { ArrayList liste = new ArrayList(); Random r = new Random(); for (int i = 0; i < 5; i++) { liste.add(new Integer(r.nextInt(101))); } System.out.println("Ausgabe der Liste :"); gibAus(liste); // sortiert System.out.println("------------------------\nAusgabe der sortierten Liste :"); Collections.sort(liste); gibAus(liste); // mit generateRandom erzeugte Liste System.out.println("------------------------\nAusgabe der sortierten Liste von generateRandom:"); Collection c = generateRandom(5, -10, 20); Collections.sort((List)c); gibAus(c); } } Lösung zu Aufgabe 19 package collections; import import import import import java.util.Arrays; java.util.Date; java.util.HashSet; java.util.TreeSet; java.util.Vector; public class MengenDemo { public static void main(String args[]) { TreeSet treeSet = new TreeSet(); HashSet hashSet = new HashSet(); String vieleWorte[] = { "möchtest", "du", "wertvolle", "dinge", "sehen", "so", "blicke", "dorthin", ",", "wohin", "die", "große", "menge", "nicht", "sieht" }; 46 treeSet.addAll(Arrays.asList(vieleWorte)); hashSet.addAll(Arrays.asList(vieleWorte)); System.out.println("treeSet: " + treeSet); System.out.println("hashSet: " + hashSet); treeSet.add("so"); hashSet.add("so"); // treeSet.add( new Date() ); // java.lang.ClassCastException: java.lang.String hashSet.add(new Date()); // O.K. in einem Hashset, da es keine Vergleiche gibt Vector vector = new Vector(); vector.addAll(Arrays.asList(vieleWorte)); System.out.println("vector: " + vector); } } Lösung zu Aufgabe 20 package collections; import java.util.HashMap; import java.util.Map; public class Feld2Map { public static void main(String[] args) { String feld[][] = new String[][] { { "rot", "#FF0000" }, { "grün", "#00FF00" }, { "blau", "#0000FF" } }; Map colorMap = toMap(feld); System.out.println(colorMap); // Aus dem Array blau finden for (int i = 0; i < feld.length; i++) { if (feld[i][0].equals("blau")) System.out.println(feld[i][1]); } // Aus der Map blau finden System.out.println(colorMap.get("blau")); } public static Map toMap(String[][] f) { Map m = new HashMap(); for (int i = 0; i < f.length; i++) { m.put(f[i][0], f[i][1]); } return m; } } Lösung zu Aufgabe 21 package collections; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Lotto { public static void main( String args[] ) { List randomList = new ArrayList(); //Liste füllen for ( int i = 1; i <= 49; ++i) randomList.add( new Integer(i) ); //Liste mischen Collections.shuffle( randomList ); 47 //Subliste erzeugen List lottoList = randomList.subList( 0, 7 ); //Subliste sortieren Collections.sort( lottoList ); //Subliste ausgeben System.out.println( lottoList ); } } Lösung zu Aufgabe 22 package collections; import java.awt.Point; import java.util.Arrays; import java.util.Comparator; class PointComparator implements Comparator { public int compare(Object o1, Object o2) { Point p1 = (Point) o1; Point p2 = (Point) o2; double d1 = ((Point) o1).distanceSq(0, 0); double d2 = ((Point) o2).distanceSq(0, 0); return (d1 < d2 ? -1 : (d1 == d2 ? 0 : 1)); } } public class PointComparatorTest { public static void main(String args[]) { Point points[] = { new Point(9, 3), new Point(3, 4), new Point(4, 3), }; Arrays.sort(points, new PointComparator()); System.out.println(Arrays.asList(points)); } } 48 2.7 Lösungen - 17.06.2005: Exceptions Lösung zu Aufgabe 23 package exceptions; public class FehlerBehandlung { public static void main(String args[]) { try { Fehler.fehler1(); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Fehler1: " + e); } try { Fehler.fehler2(); } catch (ArithmeticException e) { System.out.println("Fehler2: " + e.toString()); } } } Lösung zu Aufgabe 24 package exceptions; public class ArrayException { public static void main(String[] args) { int array[] = new int[] { 10, 20, 30, 40, 50 }; int counter = 0; /* * wir bauen eine Endlosschleife, wird verlassen wenn die * ArrayIndexOutOfBoundException fliegt */ try { while (true) { System.out.println(array[counter]); counter++; } } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Fertig"); } } } Lösung zu Aufgabe 25 package exceptions; class Singleton { static Singleton instanz; public Singleton() throws SingletonException { if (instanz != null) throw new SingletonException(); else { instanz = this; System.out.println("Singleton-Objekt erzeugt"); } } public static Singleton getInstance() { return instanz; } } package exceptions; class SingletonException extends Exception { 49 public SingletonException() { super("Man kann doch nur ein einziges Exemplar erzeugen !!!"); } } 50 2.8 Lösungen - 24.06.2005: Streams und Dateien Lösung zu Aufgabe 26 package streams; import import import import java.io.File; java.util.ArrayList; java.util.Collections; java.util.Iterator; public class FileLister { public static void main(String args[]) { ArrayList files = new ArrayList(); ArrayList dirs = new ArrayList(); FileLister fw = new FileLister(); File file = new File("/"); File all[] = file.listFiles(); for (int i = 0; i < all.length; i++) { if (all[i].isFile()) { files.add(all[i].getName()); } else dirs.add("[" + all[i].getName() + "]"); } Collections.sort(files); Collections.sort(dirs); print(dirs.iterator()); print(files.iterator()); } public static void print(Iterator i) { while (i.hasNext()) { System.out.println((String) i.next()); } } } Lösung zu Aufgabe 27 package streams; import java.io.File; import java.util.ArrayList; import java.util.Collection; public class FindFile { public static void main(String[] args) { String path = "/home/harald"; String fileName = "hallo.txt"; findFile(path, fileName); } public static void findFile(String path, String search) { Collection c = new ArrayList(); File f = new File(path); File files[] = f.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].getName().equals(search)) System.out.println(files[i].getAbsolutePath()); // damit wird nicht in versteckten Verz. gesucht if (files[i].isDirectory() && !files[i].getName().startsWith(".")) { findFile(files[i].getAbsolutePath(), search); } } } } 51 Lösung zu Aufgabe 28 package streams; import java.io.*; import java.util.*; public class Namen { public static void main(String args[]) { ArrayList namen = new ArrayList(); try { RandomAccessFile datei = new RandomAccessFile( "/home/harald/temp/namen.txt", "r"); String s; while ((s = datei.readLine()) != null) namen.add(s); datei.close(); Collections.sort(namen, new MyComparator()); System.out.println(namen); Iterator i = namen.iterator(); while(i.hasNext()) { System.out.println(i.next()); } } catch (IOException e) { System.out.println(e); } } } class MyComparator implements Comparator { public int compare(Object o1, Object o2) { String s1 = (String)o1; String s2 = (String)o2; if (s1.length() < s2.length()) return -1; else if(s1.length() > s2.length()) return 1; else return s1.compareTo(s2); } } Lösung zu Aufgabe 29 package streams; import java.io.FileWriter; import java.io.IOException; public class NameInDatei { public static void main(String[] args) { try { FileWriter writer = new FileWriter("/home/harald/testdatei.txt",true); writer.write("Harald Wehr\n"); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } 52 2.9 Lösungen - 30.06.2005: Wiederholung Lösung zu Aufgabe 30 X X Die Ausführung der main-Methode erfolgt über einen polymorphen Aufruf. Grund: main ist static, wird ohne Objekt aufgerufen Es gibt keine Klassen ohne Konstruktor. Grund: Der implizite Konstruktor ist in Klassen ohne explizite Konstruktoren immer vorhanden X Eine Klasse hat entweder nur static-Methoden oder keine static-Methoden. Grund: in einer Klasse sind sowohl Instanz- als auch Klassenmethoden erlaubt Java-Objekte können das Ende des Blocks, in dem sie erzeugt wurden, überleben. Grund: falls eine Referenz von außerhalb des Blocks auf sie zeigt überlebt die Instanz X Lösung zu Aufgabe 31 X X Instanzen werden in Java bei der Deklaration der Instanznamensvariablen erzeugt. Die spezielle Variable this beinhaltet immer die Referenz auf die aktuelle Instanz. X Klassenvariablen werden mit dem Schlüsselwort protected deklariert. X Konstuktoren können in Java genau so wie andere Methoden überladen werden. X Jede Instanz besitzt eigene Werte für die Instanzvariablen. X Durch das Schlüsselwort new wird der Konstruktor einer Klasse aufgerufen. X Mit dem Modifikator protected versehene Java-Methoden sind nur in der Klasse verwendbar, in der sie definiert wurden. X Java unterstützt Mehrfachvererbung durch das Schlüsselwort extends X Eine Instanzmethode darf in ihrem Rumpf andere Klassenelemente verwenden. X Eine Klassenmethode darf in ihrem Rumpf nicht das Schlüsselwort this verwenden. X Eine Klassenvariable muss in einer Methode initialisiert werden. X Ein Interface kann mittels implements mehrere andere Interfaces implementieren. 53 X Beim Überschreiben einer Methode müssen deren Zugriffsrechte berücksichtigt werden. X Ein abstrakt deklarierter Konstruktor ergibt keinen Sinn. X javac erzeugt plattformunabhängigen Bytecode. X Klassen können in Java höchstens eine direkte Superklasse besitzen. X Instanzmethoden können public static deklariert werden. X Die Klasse Object ist in Java Subklasse jeder anderen Klasse. X Symbolische Konstanten werden mit private deklariert. Lösung zu Aufgabe 32 1. Methode benötigt Rückgabetyp. 2. „x“ in „X“ darf nicht private sein. 3. C muss beide Methoden implementieren. 4. Index muss von 0 bis 4 laufen Lösung zu Aufgabe 33 1. Programm kompiliert nicht. Die Methode print() ist keine Klassen- sondern Instanzmethode. Damit kann diese nicht an die Klasse A gesendet werden, sondern nur an Instanzen von A. 2. Programm kompiliert nicht. Es gibt keinen parameterlosen Konstruktor in A 3. Programm in Ordnung. Es wird die Zahl 35 auf dem Bildschirm ausgegeben. 4. Programm in Ordnung. B erbt von A somit auch die statische Methode print(String s). Es wird Ausdruck: Test auf dem Bildschirm ausgegeben. 5. Programm in Ordnung. Die Methode print() der Klasse B5 überschreibt die Methode print() aus der Klasse A. Das Statement b.print() gibt die Zahl 20 auf dem Bildschirm aus. Das Statement a.print() gibt ebenfalls 20 aus, obwohl die Variable a vom Typ A ist. Grund ist das dynamische Binden, zur Laufzeit sieht der Interpreter dass in der Variable a vom Typ A tatsächlich ein B5 steckt und führt die print()-Methode von B5 aus. 54 Lösung zu Aufgabe 34 package forms; public abstract class Form { protected double x, y; public abstract double flaeche(); public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } } package forms; public class Kreis extends Form { protected double radius; public Kreis(double x, double y, double radius) { setX(x); setY(y); setRadius(radius); } public void setRadius(double radius) { this.radius = radius; } public double getRadius() { return radius; } public double flaeche() { return Math.PI * radius * radius; } public String toString() { return "Kreis(x = " + x + ",y = " + y + "), Radius r = " + radius + ", Flaeche = " + flaeche() + "!"; } } package forms; public class Rechteck extends Form { double breite, hoehe; public Rechteck(double x, double y, double breite, double hoehe) { setX(x); setY(y); setBreite(breite); setHoehe(hoehe); } public void setHoehe(double hoehe) { this.hoehe = hoehe; } public void setBreite(double breite) { this.breite = breite; } public double getHoehe() { return hoehe; } public double getBreite() { return breite; 55 } public double flaeche() { return breite * hoehe; } public String toString() { return "Rechteck(x = " + x + ",y = " + y + "), Breite = " + breite + ", Hoehe = " + hoehe + ", Flaeche = " + flaeche() + "!"; } } package forms; import java.util.ArrayList; import java.util.Iterator; public class FormContainer { private static final int MAX = 10; private ArrayList list = new ArrayList(); private int count; public void add(Form f) { list.add(f); } public double gesamtFläche() { double summe = 0; Iterator i = list.iterator(); while(i.hasNext()) { summe = summe + ((Form)i.next()).flaeche(); } return summe; } } package forms; public class FormDemo { public static void main( String args[] ) { Rechteck re = new Rechteck(0,0,4,5); Kreis kr = new Kreis( 0,0,5); FormContainer cont = new FormContainer(); System.out.println(kr); System.out.println(re); cont.add(kr); cont.add(re); System.out.println("\nDie Summe aller Flaechen betraegt: " + cont.gesamtFläche()); } } Lösung zu Aufgabe 35 class A { public A() { System.out.println("Klasse A - Konstruktor ohne Parameter"); } } class B extends A { public B() { System.out.println("Klasse B - Konstruktor ohne Parameter"); } } class C extends B { public C() { System.out.println("Klasse C - Konstruktor ohne Parameter"); } } 56 Ausgabe: Exemplar von A wird angelegt Klasse A - Konstruktor ohne Parameter Exemplar von B wird angelegt Klasse A - Konstruktor ohne Parameter Klasse B - Konstruktor ohne Parameter Exemplar Klasse A Klasse B Klasse C von C wird angelegt - Konstruktor ohne Parameter - Konstruktor ohne Parameter - Konstruktor ohne Parameter Lösung zu Aufgabe 36 class Alpha { static int objektanzahl = 0; int nummer; public Alpha() { objektanzahl++; nummer = objektanzahl; System.out.println("Objekt " + nummer + " erzeugt"); } protected void finalize() throws Throwable { System.out.println("Objekt" + nummer + " wurde geloescht"); } public static void main(String[] args) { for (int i = 0; i < 10000; i++) { new Alpha(); } } } Lösung zu Aufgabe 37 public class MeinPunkt { int x; int y; public MeinPunkt() { System.out.println("Standard-Konstruktor"); x = 0; y = 0; } public MeinPunkt(int u) { System.out.println("Konstruktor mit einem Parameter: x = " + u); x = u; y = 0; } public MeinPunkt(int u, int v) { System.out.println("Konstruktor mit zwei Parametern: x = " + u + " y = " + v); x = u; y = v; } public int getX() { return x; } public int getY() { return y; } public void print() { System.out.println("x = " + x); 57 System.out.println("y = " + y); } public static void main(String args[]) MeinPunkt p1 = new MeinPunkt(); MeinPunkt p2 = new MeinPunkt(3); MeinPunkt p3 = new MeinPunkt(3, 5); System.out.println("Die Koordinaten p1.print(); System.out.println("Die Koordinaten p2.print(); System.out.println("Die Koordinaten p3.print(); } { des Punktes p1 sind :"); des Punktes p2 sind :"); des Punktes p3 sind :"); } Lösung zu Aufgabe 38 package telefon; public class Anschluss { public boolean belegt = false; public int einheiten; public void anrufen() throws BelegtAusnahme { if (this.belegt == true) throw new BelegtAusnahme(); else this.belegt = true; }; public void auflegen() { this.belegt = false; }; public boolean istBelegt() { return belegt; } public int getEinheiten() { return einheiten; } } package telefon; public class ISDNAnschluss { private Anschluss leitung1, leitung2; public ISDNAnschluss() { leitung1 = new Anschluss(); leitung2 = new Anschluss(); } public void anrufen() throws BelegtAusnahme { try { leitung1.anrufen(); } catch (BelegtAusnahme a) { leitung2.anrufen(); } } public void auflegen() { if (leitung1.istBelegt()) leitung1.auflegen(); else leitung2.auflegen(); } public boolean istBelegt() { return leitung1.istBelegt() && leitung2.istBelegt(); } public int getEinheiten() { return leitung1.getEinheiten() + leitung2.getEinheiten(); } } 58 package telefon; public class BelegtAusnahme extends Exception { } Lösung zu Aufgabe 39 public class Hochhaus { // Attribute private double breite; private double laenge; private int anzEtagen; private double hoeheEtage; // Konstruktor public Hochhaus(double b, double l, int n, double h) { breite = b; laenge = l; anzEtagen = n; hoeheEtage = h; } public double hoehe() { return anzEtagen * hoeheEtage; } public int anzFahrstuehle() { if (anzEtagen >= 5) { if (hoehe() < 30) return 1; if (hoehe() < 50) return 2; return 3; } return 0; } public int berechneBauzeit() { return 20 + 5 * anzEtagen; } public double berechneWohnflaeche() { double grundflaeche = breite * laenge; double gesamt = 0; for (int i = 0; i < anzEtagen; i++) { grundflaeche *= .95; gesamt += grundflaeche; } return gesamt; } public double berechneGewinn(int jahr) { double baukosten = 200000 + 450 * anzEtagen * breite * laenge + 70000 * anzFahrstuehle(); double jaehrlich = baukosten * .05; double miete = berechneWohnflaeche() * 60; return (miete - jaehrlich) * jahr - baukosten; } // Testmethode (koennte auch in einer eigenen Klasse stehen) public static void main(String[] args) { Hochhaus h = new Hochhaus(32, 18, 10, 3.8); System.out.println("Bauzeit: " + h.berechneBauzeit() + " Tage"); System.out.println("Gesamtwohnflaeche: " + h.berechneWohnflaeche() + " m2"); for (int i = 0; i <= 20; i++) System.out.println("Gewinn im Jahr " + i + ": " + h.berechneGewinn(i)); } } 59