Einführung in die Programmierung ¨Ubungsblatt 9: Objekt

Werbung
Ludwig-Maximilians-Universität München
Institut für Informatik
Prof. Dr. Christian Böhm
Annahita Oswald, Bianca Wackersreuther
München, 18.12.2009
Einführung in die Programmierung
WS 2009/10
Übungsblatt 9: Objekt-Orientierung
Besprechung: 11./13./14./15.01.10
Dieses Blatt geht nicht in die Bonusregelung ein.
Aufgabe 9-1
0 Punkte
Objektorientierter Entwurf
Gegeben ist folgendes UML-Klassendiagramm zur Modellierung von Flugbuchungen:
Flug
*
- nummer : int
1
Flugzeug
- typ : String
- anzahlPlaetze : int
+ Flug(int, Pilot, Flugzeug)
+ buchen(Passagier) : boolean
+ stornieren(Passagier) : boolean
+ getAnzahlPassagiere() : int
- freierPlatz() : Platz
+ Flugzeug(String, int)
+ getAnzahlPlaetze() : int
+ getTyp() : String
*
1
Passagier
Pilot
1
Platz
- name : String
- name : String
- nummer : int
+ Pilot(String)
+ getName() : String
+ Passagier(String)
+ getName() : String
+ Platz(int)
+ getPassagier() : Passagier
+ setPassagier(Passagier) : void
+ getNummer() : int
Implementieren Sie diese Klassen in Java.
1
Lösungsvorschlag:
/**
* Klasse zur Modellierung eines Sitzplatzes.
*/
public class Platz
{
/**
* Die Nummer des Platzes
*/
private int nummer;
/**
* Der Passagier, der diesen Platz gebucht hat
*/
private Passagier passagier;
/**
* Erzeugt einen Platz mit der angegebenen Platznummer.
*
* @param nummer die Nummer des Platzes
*/
public Platz(int nummer){
this.nummer = nummer;
}
/**
* Gibt den Passagier, des diesen Platz gebucht hat, zurück.
*
* @return der Passagier, der diesen Platz gebucht hat
*/
public Passagier getPassagier(){
return this.passagier;
}
/**
* Bucht diesen Platz f¨r den angegebenen Passagier.
*
* @param passagier der Passagier, der auf diesen Platz gebucht wird
*/
public void setPassagier(Passagier passagier){
this.passagier = passagier;
}
/**
* Gibt die Nummer dieses Platzes zurück.
*
* @return die Nummer dieses Platzes
*/
public int getNummer(){
return this.nummer;
}
}
2
/**
* Klasse zur Modellierung eines Flugzeugs.
*/
public class Flugzeug
{
/**
* Der Typ dieses Flugzeugs
*/
private String typ;
/**
* Die Anzahl möglicher Plätze in diesem Flugzeug
*/
private int anzahlPlaetze;
/**
* Erzeugt ein neues Flugzeug mit dem angebenen Typ und
* der angegebenen Anzahl von Plätzen.
*
* @param typ der Typ dieses Flugzeugs
* @param anzahlPlaetze die Anzahl möglicher Plätze
* in diesem Flugzeug
*/
public Flugzeug(String typ, int anzahlPlaetze){
this.typ = typ;
this.anzahlPlaetze = anzahlPlaetze;
}
/**
* Gibt die Anzahl von möglichen Plätzen in
* diesem Flugzeug zurück.
*
* @return die Anzahl möglicher Plätze
*/
public int getAnzahlPlaetze(){
return this.anzahlPlaetze;
}
/**
* Gibt den Flugzeug-Typ aus.
*
* @return der Flugzeug-Typ
*/
public String getTyp(){
return this.typ;
}
}
3
/**
* Klasse zur Modellierung eines Piloten.
*/
public class Pilot
{
/**
* Der Name dieses Piloten.
*/
private String name;
/**
* Erzeugt einen Piloten mit dem angegebenen Namen.
*
* @param name der Name des Piloten
*/
public Pilot(String name){
this.name = name;
}
/**
* Gibt den Namen dieses Piloten zurück.
*
* @return der Name des Piloten
*/
public String getName(){
return this.name;
}
}
/**
* Klasse zr Modellierung eines Passagiers.
*/
public class Passagier
{
/**
* Der Name dieses Passagiers
*/
private String name;
/**
* Erzeugt einen Passagier mit dem angegebenen Namen.
*
* @param name der Name des Passagiers
*/
public Passagier(String name){
this.name = name;
}
/**
* Gibt den Namen dieses Passagiers zurück.
*
* @return der Name dieses Passagiers
*/
public String getName(){
return this.name;
}
}
4
/**
* Klasse zur Modellierung eines Flugs.
*/
public class Flug {
/**
* Die Flugnummer
*/
private int nummer;
/**
* Der Pilot dieses Flugs
*/
private Pilot pilot;
/**
* Die Plätze für diesen Flug
*/
private Platz[] platz;
/**
* Erzeugt einen neuen Flug mit der gegebenen Flugnummer und dem gegebenen
* Piloten und Flugzeug.
*
* @param nummer
die Flugnummer
*
* @param pilot
der Pilot des Flugs
*
* @param flugzeug
das Flugzeug für diesen Flug
*
*/
public Flug(int nummer, Pilot pilot, Flugzeug flugzeug) {
this.nummer = nummer;
this.pilot = pilot;
this.platz = new Platz[flugzeug.getAnzahlPlaetze()];
for (int i = 0; i < this.platz.length; i++) {
this.platz[i] = new Platz(i + 1);
}
}
/**
* Bucht für einen gegebenen Passagier einen Platz in diesem Flug.
*
* @param passagier
Passagier, für den ein Platz gebucht werden soll
*
@return
Konnte
ein Platz gebucht werden?
*
/
*
public boolean buchen(Passagier passagier) {
Platz platz = freierPlatz();
if (platz != null) {
platz.setPassagier(passagier);
return true;
}
return false;
}
5
/**
* Storniert den für einen gegebenen Passagier gebuchten Platz in
* diesem Flug.
*
* @param passagier
Passagier, für den ein gebuchter Platz storniert werden
*
soll
*
* @return Konnte der Flug erfolgreich storniert werden?
*/
public boolean stornieren(Passagier passagier) {
for (Platz platz : this.platz) {
if (platz.getPassagier() == passagier) {
platz.setPassagier(null);
return true;
}
}
return false;
}
/**
* Gibt einen freien Platz für diesen Flug zurück.
*
* @return einen freien Platz für diesen Flug, <code>null</code>,
falls kein Platz mehr frei ist.
*
*/
private Platz freierPlatz() {
for (int i = 0; i < this.platz.length; i++) {
if (this.platz[i].getPassagier() == null) {
return this.platz[i];
}
}
return null;
}
/**
* Gibt die Anzahl der Passagiere aus, die für diesen Flug einen Platz
* gebucht haben.
*
* @return die Anzahl der Passagiere in diesem Flug
*/
public int getAnzahlPassagiere() {
int anzahl = 0;
for (Platz platz : this.platz) {
if (platz.getPassagier() != null) {
anzahl++;
}
}
return anzahl;
}
}
6
Aufgabe 9-2
Verbunde: Klassen / Objekte ohne Methoden
Die Datei StudentenInfo.java hat folgenden Inhalt:
public class StudentenInfo {
public static void main(String[] args) {
Student a = new Student("Peter", "Parker", new Datum(15, 8, 1962),
"parkerp");
Student b = new Student("Mary Jane", "Watson", new Datum(4, 11, 1966),
"watsonma");
System.out.println("Name: " + a.nachname + ", " + a.vorname);
System.out.println("Kennung: " + a.kennung);
System.out.println("Geboren am: " + a.geburtsdatum.tag + "."
+ a.geburtsdatum.monat + "." + a.geburtsdatum.jahr);
System.out.println("Name: " + b.nachname + ", " + b.vorname);
System.out.println("Kennung: " + b.kennung);
System.out.println("Geboren am: " + b.geburtsdatum.tag + "."
+ b.geburtsdatum.monat + "." + b.geburtsdatum.jahr);
}
}
(a) Lassen Sie die Klasse StudentenInfo unverändert und definieren Sie dazu passende Klassen Student
und Datum. Für diese Klassen brauchen Sie keine Methoden zu definieren.
Lösungsvorschlag:
/**
* Klasse zur Modellierung eines Studenten.
*/
public class Student {
/**
* Der Vorname des Studenten.
*/
public String vorname;
/**
* Der Nachname des Studenten.
*/
public String nachname;
/**
* Das Geburtsdatum des Studenten.
*/
public Datum geburtsdatum;
/**
* Die Kennung des Studenten.
*/
public String kennung;
7
/**
* Erzeugt einen Studenten mit den angegebenen Daten.
*
* @param vorname
der Vorname des Studenten
*
* @param nachname
der Nachname des Studenten
*
* @param gebDatum
das Geburtsdatum des Studenten
*
* @param kennung
die Kennung des Studenten
*
*/
public Student(String vorname, String nachname, Datum gebDatum,
String kennung) {
this.vorname = vorname;
this.nachname = nachname;
this.geburtsdatum = gebDatum;
this.kennung = kennung;
}
}
/**
* Klasse zur Modellierung eines Datums in numerischer Form. Ein Datum wird
* durch Tag, Monat und Jahr repräsentiert.
*/
public class Datum {
/**
* Tag
*/
public int tag;
/**
* Monat
*/
public int monat;
/**
* Jahr
*/
public int jahr;
/**
* Erzeugt ein Datum mit den angegebenen Werten für Tag, Monat und
* Jahr.
*
* @param tag
Tag
*
@param
monat
*
Monat
*
@param
jahr
*
Jahr
*
/
*
public Datum(int tag, int monat, int jahr) {
this.tag = tag;
this.monat = monat;
this.jahr = jahr;
}
}
8
(b) Erklären Sie, warum die Klassen Student und Datum nicht gutem objektorientiertem Programmierstil
entsprechen. Wie könnte man dies verbessern?
Lösungsvorschlag:
Das Prinzip der Kapselung wurde in den beiden Klassen Student und Datum nicht umgesetzt, da die
Attribute der Klassen jeweils als public deklariert wurden und somit auch außerhalb der Klasse sichtbar
und veränderbar sind. Dies kann verhindert werden, indem man die Attribute als private deklariert und
einen Zugriff auf die Attribute nur durch klar definierte Schnittstellen, d.h. Methoden, ermöglicht. So,
wie die Klassen jetzt sind, verwirklichen Sie den allgemeinen Datentyp “Verbund” (oder “Record”). Dies
ist in sich sinnvoll, aber es werden eben noch nicht alle Möglichkeiten der Objekt-Orientierung genutzt.
Vor allem wird kein “Verhalten” der Objekte modelliert.
Aufgabe 9-3
0 Punkte
Weihnachtsbäume aus Strings
Erstellen Sie eine Klasse Weihnachtsbaum, die Weihnachtsbäume unterschiedlicher Höhe repräsentiert.
(a) Jeder Weihnachtsbaum sei durch folgende Attribute definiert:
• Weihnachtsbaumspitze (repräsentiert durch den String "*", wird nie verändert)
• Weihnachtsbaumstamm (repräsentiert durch den String "[_]", wird nie verändert)
• Höhe des Baums
(b) Definieren Sie einen Konstruktor Weihnachtsbaum(int hoehe), der eine beliebige Höhe des zu erzeugenden Weihnachtsbaums als Parameter erhält.
(c) Die Klasse Weihnachtsbaum soll eine Methode public String zeichne() enthalten, die den Weihnachtsbaum graphisch ausgibt. Ein Beispiel für einen Weihnachtsbaum der Höhe 5 finden Sie in der unten
angegebenen Abbildung. Sie können sich hier auch weitere Hilfsmethoden implementieren. Testen Sie
Ihr Programm.
Lösungsvorschlag:
public class Weihnachtsbaum {
public static final String WEIHNACHTSBAUMSPITZE = "*";
public static final String WEIHNACHTSBAUMSTAMM = "[_]";
private int hoehe;
public Weihnachtsbaum(int hoehe) {
this.hoehe = hoehe;
}
9
public String zeichne() {
StringBuilder builder = new StringBuilder();
builder.append(fuellen(this.hoehe + 1, " "));
builder.append(WEIHNACHTSBAUMSPITZE);
builder.append(fuellen(this.hoehe + 1, " "));
builder.append("\n");
for (int i = this.hoehe; i > 0; i--) {
builder.append(fuellen(i, " "));
builder.append("/");
builder.append(abwechselndFuellen(this.hoehe - i + 1, ".", ","));
builder.append("\\");
builder.append(fuellen(i, " "));
builder.append("\n");
builder.append(fuellen(i - 1, " "));
builder.append("/");
builder.append(abwechselndFuellen(this.hoehe - i + 2, ",", "."));
builder.append("\\");
builder.append(fuellen(i - 1, " "));
builder.append("\n");
}
builder.append(fuellen(this.hoehe, "ˆ"));
builder.append(WEIHNACHTSBAUMSTAMM);
builder.append(fuellen(this.hoehe, "ˆ"));
builder.append("\n");
return builder.toString();
}
private String abwechselndFuellen(int laenge, String fuellstring1,
String fuellstring2) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < laenge; i++) {
appendString(fuellstring1, builder);
if (i + 1 < laenge) {
appendString(fuellstring2, builder);
}
}
return builder.toString();
}
private void appendString(String string, StringBuilder builder) {
builder.append(string);
}
private String fuellen(int laenge, String fuellstring) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < laenge; i++) {
builder.append(fuellstring);
}
return builder.toString();
}
public static void main(String[] args) {
Weihnachtsbaum xmastree = new Weihnachtsbaum(5);
System.out.println(xmastree.zeichne());
}
}
10
Herunterladen