Aufgabe 1

Werbung
»Programmieren«, WS 2006/2007
Nino Simunic M.A.
Nino Simunic ([email protected])
Übungsblatt 7
Die benötigten Quelltexte finden Sie hier:
http://imperia.uni-due.de/imperia/md/content/computerlinguistik/uebungsblatt_7_code.zip
Aufgabe 1
VERERBUNG IN JAVA: (OBERKLASSEN-)KONSTRUKTOREN
C.java
class A {
A( ){
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
System.out.println(">>A<<");
}
}
class B extends A{
B() {
System.out.println(">>B<<");
}
}
public class C extends B {
C() {
System.out.println(">>C<<");
}
public static void main (String [] args) {
new C();
}
}
Bevor Sie das Programm ausführen: Was ist Ihrer Meinung nach die Ausgabe?
Kompilieren und führen Sie das Programm aus.
o
Was ist die Ausgabe de facto? Entspricht die Ausgabe Ihren Erwartungen?
Formulieren Sie ein Prinzip im Kontext Vererbung, welche das beobachtbare Verhalten erklärt. Das Prinzip soll
im Kern die Reihenfolge der Aufrufe von Konstruktoren bei Vererbung beschreiben.
Warum werden Konstruktoren der Oberklasse überhaupt aufgerufen, obwohl kein super() in der vorliegenden
Mehrfachvererbung explizit verwendet wurde?
Programmieren
Nino Simunic M.A.
Seite 1
Aufgabe 2
INSTANCEOF
In dieser Aufgabe erlernen Sie den Umgang mit einem neuen, binären Operator: instanceof. Versuchen Sie zu verstehen,
was dieser Operator leistet, um ihn später auch anwenden zu können.
http://www.dpunkt.de/java/Die_Sprache_Java/Objektorientierte_Programmierung_mit_Java/48.html:
Mit dem instanceof-Operator kann zur Laufzeit geprüft werden, ob ein von einem Verweis referenziertes Objekt
zuweisungskompatibel zu einer Klasse ist, die im zweiten Operanden von instanceof angegeben wird. Der zweite Operand
darf kein Verweis sein. instanceof hat die Syntax
<Verweis oder Verweistyp> instanceof <Verweistyp>
instanceof liefert true, wenn
•
der linke Operand eine Variable mit einem Verweistyp ist und zur Laufzeit auf ein Exemplar verweist, das zu
der Klasse (oder einer Unterklasse) gehört, die der zweite Operand vorgibt.
instanceof liefert false, wenn
•
•
der linke Operand den Wert null hat, da dieser Wert anzeigt, dass auf kein Objekt verwiesen wird;
der linke Operand eine Variable mit einem Verweistyp ist und zur Laufzeit auf ein Exemplar verweist, das
nicht zu der Klasse (oder einer Unterklasse) gehört, die der zweite Operand vorgibt.
Mit instanceof kann zum Beispiel zunächst festgestellt werden, ob zwei Objekte zuweisungskompatibel sind, bevor die
eigentliche Zuweisung erfolgt.
Schauen Sie sich zur Verdeutlichung den folgenden Code an:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
instanceTest.java
class Ship { /* Code */ }
class Yacht extends Ship { /* Code */ }
class Carrier extends Ship { /* Code */ }
public class instanceTest {
public static void main (String[] args){
/*
Links deklarierter Typ, rechts tatsächlicher Typ */
Ship speedy
=
new Yacht();
Ship nimitz
=
new Carrier();
if ( speedy instanceof Yacht ){System.out.println("Is a yaught!");}
if ( nimitz instanceof Carrier ){ System.out.println("Is a carrier!");}
if ( nimitz instanceof Ship ){ System.out.println("Is also a ship!");}
}
}
Programmieren
Nino Simunic M.A.
Seite 2
Dank Polymorphie (und dank Informatik ;) sind die Zeilen 8-10 erst möglich: Eine Objektreferenz kann an eine Variable
anderen (kompatiblen!) Typs zugewiesen werden, wenn der Typ dieser Variablen in der Vererbungshierarchie höher steht als
der Typ des zuzuweisenden Objekts: Yacht ist eine abgeleitete Klasse von Ship, und somit ist die Zuweisung an einer
Variable vom (höheren) Typ Ship in Ordnung. Für Zeile 10 gilt Analoges. Da also ein Objekt Instanz seiner Klasse und aller
in der Hierarchie höher angesiedelten Klassen ist, wird die Bedingung in Zeile 15 auch als true ausgewertet.
Ändern Sie die main-Methode so wie unterhalb angegeben, und führen Sie das Programm dann aus.
instanceTest.java (nur main-Methode)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main (String[] args){
Ship seaStar = new Yacht();
if ( seaStar instanceof Ship ) {
System.out.println("Is a boring ship!");
}
else if ( seaStar instanceof Carrier ) {
System.out.println("Is a carrier!");
}
else if ( seaStar instanceof Yacht ) {
System.out.println("Is a nice yacht!");
}
}
Die Ausgabe ist zwar nicht »falsch«, jedoch nicht gewollt: Es soll der tatsächliche Typ ausgegeben werden.
Ändern Sie die Kontrollstruktur so, dass der tatsächliche Typ ausgegeben wird. Es sollen alle Überprüfungen
noch immer vorgenommen werden.
Ändern Sie den Typ von seaStar zu Yacht. Warum (und wo) lässt sich das Programm jetzt nicht mehr
kompilieren?
Aufgabe 3
PERSONEN-REPOSITORY, INSTANCEOF
Besorgen Sie sich die Klassen Person.java, Student.java, Lecturer.java aus der letzten Vorlesung, bzw. via Link
am Anfang des Übungsblatts. Ihre Aufgabe besteht darin, die unterhalb aufgeführte Repository-Klasse um die Methode isA
zu erweitern. Die Methode isA soll als Rückgabewert ein String besitzen, welcher den Typ des übergebenen Objekts
beschreibt: "Person“, "Student“, bzw. "Lecturer“. Verwenden Sie als Gerüst und zum Testen die nachstehende Klasse, die
bereits Aufrufe der (noch nicht existierenden) isA-Methode in der main-Methode enthält.
Programmieren
Nino Simunic M.A.
Seite 3
1
2
3
4
5
6
7
8
9
10
11
12
13
Repository.java
public class Repository {
// ... isA( ... ) { ... }
public static void main(String[] args){
Person[] repository = new Person[3];
repository[0] =
new Person("Pladimir Vutin", "1.4.1955", 'f');
repository[1] =
new Student("Ochse Uwenknecht","7.8.1982",'m',100001000);
repository[2] =
new Lecturer("Dr. Mabuse", "9.9.1915", 'm', 195644432, 15000);
System.out.println( isA(repository[0])+": "+
repository[0].toString() );
System.out.println( isA(repository[1])+": "+
repository[1].toString() );
System.out.println( isA(repository[2])+": "+
repository[2].toString() );
}
}
Wenn Sie die isA-Methode korrekt implementiert haben, ist die Ausgabe:
Person: Pladimir Vutin, 1.4.1955, f
Student: Ochse Uwenknecht, 7.8.1982, m, 100001000
Lecturer: Dr. Mabuse, 9.9.1915, m, 195644432, 15000.0
Enthält Ihre Methode eine if-else if(-else) Kontrollstruktur, müssen Sie auch darauf achten, dass jeder erreichbare und
ausführbare Teil (auch der else-Rumpf, der nicht zwingend explizit via else manifestiert werden muss) auch eine returnAnweisung enthält!
Aufgabe 4
PKW-VERERBUNG
Modellieren Sie die folgenden Konzepte, indem Sie sie als Klassen Auto, Pickup und AutoTest verwirklichen.
Eigenschaften von Objekten dieser Klassen sollen ausschließlich beim Erzeugen gesetzt und ggf. durch Methoden verändert
werden können.
Auto: Ein Auto soll ein Kennzeichen, einen Kilometerstand und eine Anzahl Sitzplätze haben. Wenn nicht anders
angegeben, ist das Kennzeichen eines Auto–Objekts standardmäßig »DO-OM 3«, es sollen aber auch Autos mit anderen
Kennzeichen erzeugt werden können. Ein neu erzeugtes Auto hat grundsätzlich noch keine Kilometer gefahren. Wenn nicht
anders angegeben, so hat ein Auto 5 Sitzplätze. Es sollen jedoch auch zweisitzige Autos erzeugt werden können. Zu guter
Letzt hat ein Auto eine Antenne, die aus- oder eingefahren werden/sein kann. Die Klasse soll mindestens die folgenden
Methoden besitzen:
Programmieren
Nino Simunic M.A.
Seite 4
public String getKennzeichen() : liefert das Kennzeichen zurück
public int getKilometerstand() : liefert den aktuellen Kilometerstand zurück
public void fahre(int x) : schreibt eine Meldung an die Standardausgabe, dass das Auto x Kilometer
fährt, und setzt dann den Kilometerstand entsprechend weiter
public void antenneEinfahren() : schreibt eine Meldung an die Standardausgabe, dass die Antenne
eingefahren wird, und setzt den Status der Antenne
public void antenneAusfahren() : schreibt eine Meldung an die Standardausgabe, dass die Antenne
ausgefahren wird, und setzt den Status der Antenne
public boolean istAntenneDraussen() : liefert genau dann true, wenn die Antenne ausgefahren ist
protected void vorDemWaschen() : bereitet das Auto auf den Aufenthalt in der Waschstraße vor – konkret
bedeutet das bei einem Auto, dass die Antenne eingefahren wird
public void waschen() : bereitet das Auto für eine Wagenwäsche vor und schreibt dann eine Meldung an
die Standardausgabe, dass der Wagen gewaschen wird
public int getSitzplaetze() : liefert die Anzahl Sitzplätze zurück
public boolean equals(Object o) : ergibt genau dann true, wenn das Objekt o ebenfalls ein Auto ist,
und wenn die beiden Kennzeichen gleich sind
public String toString() : gibt eine passende String–Repräsentation des Autos zurück
Pickup: Ein Pickup ist für unsere Zwecke eine spezielle Art von Auto. Es hat nur 2 Sitzplätze, dafür jedoch zusätzlich eine
offene Ladefläche mit einem beim Erzeugen bestimmbaren Fassungsvermögen f. Die Ladefläche ist beim Erzeugen des
Pickups zunächst leer und kann maximal mit f Dingen beladen werden. Die Klasse muss mindestens folgende Methoden
besitzen:
public boolean beladen(int x) : falls auf der Ladefläche noch genügend Platz ist, wird der Inhalt der
Ladefläche um x Dinge erhöht, eine passende Meldung an die Standardausgabe geschrieben, und true
zurückgegeben, andernfalls false
public void entladen(int x) : falls auf der Ladefläche mindestens x Dinge vorhanden sind, wird der
Inhalt der Ladefläche um x Dinge erniedrigt, eine passende Meldung geschrieben, und true zurückgegeben,
andernfalls false
protected void vorDemWaschen() : bei einem Pickup soll vor dem Waschen nicht die Antenne eingefahren
werden, sondern stattdessen die Ladefläche geleert werden
public int getLadung() : liefert die Anzahl Dinge, die derzeit auf der Ladefläche liegen, zurück, ohne den
Ladezustand zu verändern
public String toString() : gibt eine passende String–Repräsentation des Pickups zurück
AutoTest: Diese Klasse ist ausschließlich zum Testen der Klassen Auto und Pickup da. Definieren Sie in AutoTest eine
passende main–Methode, in der mehrere verschiedene Autos und Pickups erzeugt werden. Dort ist unter anderem
Folgendes zu implementieren:
Lassen Sie sich die Kennzeichen und sonstigen Zustände der erzeugten Objekte ausgeben.
Lassen Sie die Autos und Pickups fahren, waschen. Testen Sie sie untereinander auf Gleichheit.
Testen Sie die Beladelogik der Pickups.
Hinweis: Der Modifikator protected bewirkt bei Methoden und Variablen, dass diese nur innerhalb der betreffenden Klasse
und aller Klassen, die von ihr erben, sichtbar sind. Der Modifikator private dagegen bewirkt eine Sichtbarkeit
nur innerhalb der betreffenden Klasse. Der Modifikator public bewirkt eine allgemeine Sichtbarkeit.
Programmieren
Nino Simunic M.A.
Seite 5
Herunterladen