Aufgabe 1 OOP

Werbung
»Programmieren«, WS 2006/2007
Nino Simunic M.A.
Nino Simunic ([email protected])
Übungsblatt 4
Aufgabe 1
OOP
In dieser Aufgabe sollen Sie Autos als Klasse Car modellieren. Die Eigenschaften auf attributiver Ebene sind:
-
Die Beschreibung des PKW
Die Tankkapazität, bspw. 60 (l)
Der Tankinhalt, bspw. 24.5 (l)
Der Spritverbrauch, bspw. 5.7 (l) (auf 100km)
Die maximale Reichweite des PKW, bspw. 600 (km)
Die bislang gefahrene Strecke, bspw. 400 (km)
[ carDesc ]
[ fuelCap ]
[ fuel ]
[ fuelConsum ]
[ maxRange ]
[ drivenKm ]
Ein beliebiges Car-Objekt soll die Möglichkeit haben, eine Strecke zu hinterlegen. Dabei soll angegeben werden können
(Parameter), wie weit das Auto fahren soll. Diese Streckenangabe soll dann verwendet werden, den Spritverbrauch für die
zurückzulegende Strecke zu berechnen und den verbrauchten Sprit vom Tankinhalt abzuziehen. Außerdem ist eine Methode
in der Klasse zu implementieren, welche alle Daten zur aktuellen PKW-Instanz als (konkatenierten) String zurückgibt, um
ebenjene bspw. auf dem Bildschirm ausgeben zu können. Es sind neben den Instanzvariablen folglich die nachstehenden
Methoden zu implementieren:
-
Fahren
Informationen ausgeben
[ void drive( int distance ){ } ]
[ public1 String toString( ){ } ]
Bisher haben Sie nur Methoden kennengelernt, die keinen Rückgabewert produzieren. Diese müssen mit dem Schlüsselwort
void im Methodenkopf definiert werden. Alle anderen Methoden geben den Typ des Rückgabewerts an, also wie bereits
vorgeschlagen: String toString(){}. Die Angabe eines Rückgabetyps verpflichtet dazu, einen Wert entsprechenden
Typs auch zurückzugeben, und zwar via Schlüsselwort return (gefolgt vom Rückgabewert) innerhalb der Methode.
Dabei ist auch zu beachten, dass die return-Anweisung als zuletzt durchführbare Anweisung implementiert wird. Zur
Verdeutlichung schauen Sie sich einmal die folgenden Varianten an:
1
2
3
4
5
6
1
Code-Ausschnitt 1 (Methode mit String-Rückgabewert)
//...
public String toString(){
String theString = "Alle "+"relevanten ";
theString = theString + "Informationen sind hier\n"; //Konkatenation
return theString;
}//...
public ist in diesem Fall Pflicht!
Programmieren
Nino Simunic M.A.
Seite 1
Code-Ausschnitt 2 (Methode mit String-Rückgabewert)
//...
public String toString(){
return "Alle relevanten Informationen sind hier\n";
}//...
1
2
3
4
Wenn eine solche Methode mit Rückgabewert aufgerufen wird, kann (muss aber nicht) an aufrufender Stelle der
Rückgabewert »aufgefangen«/verwendet werden, bspw. als Zuweisung zu einer Variablen kompatiblen Typs!
ReturnTest.java
public class ReturnTest {
1
2
3
4
5
6
7
8
9
10
11
12
14
public String toString( ){
return "Informationen...";
}
public static void main ( String args[] ){
ReturnTest rt = new ReturnTest();
System.out.println( rt.toString() );// Bspw. so,
String myString = rt.toString();
// oder als Zuweisung.
System.out.println( myString );
// Wie in Zeile 9, nur mit Var.
}
}
http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/ReturnTest.java
Hier noch ein paar Formeln, die Sie benötigen werden, als Pseudocode:
Maximale Reichweite = Tankinhalt * 100 / Spritverbrauch
Verbrauchter Sprit = Spritverbrauch * Strecke / 100
Achten Sie bei der Implementierung auf die folgenden Besonderheiten:
-
Wenn der verbrauchte Sprit den Tankinhalt überschreitet, wird in diesem Fall der Tankinhalt (fuel) auf 0
gesetzt, sowie die gefahrene Strecke (drivenKm) des Autos auf die max. Reichweite gesetzt.
Programmieren
Nino Simunic M.A.
Seite 2
Als Klassengerüst für die Car-Klasse dient Ihnen die folgende Implementierung:
Car.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Car {
/* Instanzvariablen (attribute Eigenschaften) */
/* Konstruktor */
public String toString( ){
// Anweisungen + return-Statement zum Schluss
}
void drive( int distance ){
// Anweisungen
}
}
Nehmen Sie bitte die folgende Klasse CarTest, um Car-Objekte von Ihrer Car-Klasse zu erzeugen und das Programm zu
testen.
CarTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
public class CarTest {
public static void main ( String[] args ) {
Car golfv = new Car( "Golf V TDI", 60, 6.2, 60.0);
System.out.println( "Spritztour ins Allgäu bitte: 600 km");
golfv.drive( 600 );
System.out.println( golfv.toString() );
System.out.println(
"\nSo, und nun zurück. "+
"Leider kein Geld mehr für's Tanken ...");
golfv.drive( 600 );
System.out.println( golfv.toString() );
}
}
http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/CarTest.java
Zur Not können Sie die main()-Methode der Testklasse oberhalb auch in Car einsetzen.
Sollten Sie auf Probleme bei Berechnungen/Zuweisungen stoßen, deren Ausdrücke sowohl double als auch int-Werte
enthalten, sollten Sie sich das folgende Programm IntCastTest.java einmal ansehen, bzw. auch mit uns in der Gruppe
diskutieren: http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/IntCastTest.java
Programmieren
Nino Simunic M.A.
Seite 3
Wenn Sie alles richtig gemacht haben, sieht die Ausgabe im Idealfall etwas so aus:
Spritztour ins Allgäu bitte: 600 km
Car: Golf V TDI
Fuel capacity:
60 l
Fuel consumption:
6.2 l
Current fuel:
22.799999999999997 l
Max. range:
967 km
Recently driven km: 600 km
So, und nun zurück. Leider kein Geld mehr für's Tanken ...
Car: Golf V TDI
Fuel capacity:
60 l
Fuel consumption:
6.2 l
Current fuel:
0.0 l
Max. range:
967 km
Recently driven km: 967 km
Aufgabe 2
CAR-ERWEITERUNGEN, TEIL 1
-
Erweitern Sie Ihre Car-Klasse um einen weiteren Konstruktor, der ohne die Angabe von fuel auskommt. In
diesem Fall wird die vorhandene Menge Sprit (fuel) einfach auf den maximalen Wert, d.h. die Tankkapazität,
gesetzt (fuelCap).
-
Fügen Sie der Car-Klasse eine Methode public void setFuel( int fuelAmount ) { } hinzu, welche
das Betanken ermöglicht. Für die Funktionalität dieser Methode ist zu beachten:
o
Wenn die angegebene Menge (fuelAmount) größer 0 ist, und die Summe aus der aktuell
vorhandenen Spritmenge (fuel) und der zu tankenden Menge (fuelAmount) die Tankkapazität
(fuelCap) nicht überschreitet, wird fuelAmount zu fuel addiert.
o
Ansonsten (d.h., wenn bspw. negative Werte oder fuel-überschreitende Werte als Argument
übergeben werden) wird fuel auf das Maximum gesetzt (fuelCap)
o
In beiden Fällen wird der Tachostand (drivenKm) auf 0 gesetzt, und die Reichweite (maxRange) auf
Basis der neuen Werte berechnet.
-
Eventuell ist es sinnvoll, die Berechnung der maximalen Reichweite in eine separate Methode
zu schreiben, um Redundanzen im Code zu vermeiden.
Nur bei der Ausgabe der Car-Informationen sollen double-Werte gerundet und nur mit zwei
Nachkommastellen angezeigt werden. Benutzen Sie dazu die (statische) Methode round der Klasse Math.
Auch in diesem Fall kann ein Blick in die Java-API nicht schaden. Hier ein kleines Anwendungsbeispiel:
double myD = 2.9876543;
double myRoundedD = Math.round( myD * 100. ) / 100.;
//myRoundedD hat den Wert 2.99
-
Welchen Vorteil bietet nun eigentlich die Methode setFuel( )? Man könnte ja theoretisch die Attribute
händisch modifizieren, wenn man »tankt«, d.h. carObject.fuel = 10; carObject.maxRange = 500;?
Programmieren
Nino Simunic M.A.
Seite 4
Aufgabe 3
CAR-ERWEITERUNGEN, TEIL 2
Sie erhalten für diese Aufgabe eine bereits kompilierte Klasse Route.class inklusive Dokumentation:
http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/Route.zip
Im Moment arbeitet Ihre drive-Methode so, dass ein int-Wert übergeben werden kann, der via Argument/lokale Variable
(distance) zu weiteren Berechnungen innerhalb der Methode herangezogen wird. Ihre Aufgabe besteht nun darin, Ihre
Car-Klasse so anzupassen, dass die drive-Methode nicht mehr direkt mit einem primitiven Datentyp arbeitet/rechnet,
sondern über ein Objekt auf den Entfernungswert zugreift. D.h., dass die Parameterliste der drive( )-Methode nicht mehr
aus einem int-Parameter bestehen soll (distance) , sondern mit einen Route-Parameter definiert wird. Als
Instanzvariable der Route-Klasse existiert die Variable routeDistance vom Typ int. Mit entsprechendem Aufruf via
Punktnotation können Sie auf diesen Wert zugreifen. Prinzipiell müssen Sie dann lediglich alle Vorkommen von distance
durch route.routeDistance ersetzen, vorausgesetzt natürlich, Sie haben sich für diese vorgeschlagenen Bezeichner
entschieden.
Zur Verdeutlichung der durchzuführenden Modifikationen sehen sich Sie bitte die Vorher-Nachher Darstellung unterhalb an.
Die Anweisungen sind natürlich nur Beispiele, die Sie im Idealfall de facto nicht verwenden sollen:
// ... Vorher:
public void drive( int distance ) {
System.out.println( distance + 1 );
}// ...
------------------------------------------// ... Nachher:
public void drive( Route route ) {
System.out.println( route.distance + 1 );
}// ...
Zunächst sollten Sie sich jedoch mit der Route-Klasse ein wenig vertraut machen. Die Dokumentation sagt bereits
einiges über die Eigenschaften der Klasse aus, u.a. welche Argumente notwendig sind, um ein Route-Objekt zu
erzeugen. Was allerdings nicht in der Dokumentation steht, sind die folgenden, wohlmöglich für Sie neuen
Informationen.
Um die fertige Route-Klasse nutzen zu können, gibt es verschiedene Möglichkeiten. (Im Allgemeinen müssen Sie
beim Kompilieren der Klasse(-n), welche die Route-Klasse verwenden, den Pfad zu der kompilierten Route-Klasse mit
angeben. Diese Information ist der sogenannte classpath.) Wir einigen uns jedoch zunächst auf die folgende,
einfache Variante.
Programmieren
Nino Simunic M.A.
Seite 5
Ein Beispiel: Sie haben eine Klasse RouteTest, welche Route verwendet, geschrieben und entsprechend
gespeichert:
RouteTest.java
1
2
3
4
5
6
7
8
public class RouteTest {
public static void main(String[] args) {
Route myRoute = new Route( "Dortmund", "Duisburg", 55, 120);
System.out.println( myRoute.toString() );
}
}
http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/RouteTest.java
Angenommen, sie haben die RouteTest.java Datei im Ordner D:\javaTMP gespeichert. Legen Sie nun auch die
Route.class Datei im selben Verzeichnis (D:\javaTMP) ab und kompilieren Sie dann ihre .java-Datei (nicht die
.class-Datei) mit javac wie gehabt. Wenn Sie mehrere .java Dateien auf einmal kompilieren wollen, können Sie
dies übrigens auch mit dem Asterisk/Glob-Sternchen * tun:
javac *.java
Mit diesem (Konsolen-)Befehl werden alle Dateien, die auf .java enden und im selben Verzeichnis sind, kompiliert.
Die hier aufgeführten Schritte können Sie sich anhand des Bilds unterhalb verdeutlichen:
Heiter weiter, und gutes Gelingen!
Programmieren
Nino Simunic M.A.
Seite 6
Herunterladen