Problem mit abstrakte Klasse und Container-Klasse
-
Guten Morgen,
ich sitze an einer Semesteraufgabe, in welcher wir ein Hotel-Buchungssystem entwickeln sollen. Dabei bekommen wir wöchentlich neue Teilaufgaben.Aktuell lautet die Aufgabe:
"Ergänzen Sie Ihr Projekt um eine Klasse, welche die folgende abstrakte Klasse implementiert und somit die Reservierung von Zimmern durchführt"Die gegebene, abstrakte Klasse lautet (auszugsweise):
public abstract class Reservierungssystem { private Hotel hotel; public Reservierungssystem (Hotel h) { hotel = h; } public Hotel getHotel() { return hotel; } public abstract Reservierung buche (Kunde k, int anzBetten, Datum beginn, Datum ende); }
Objekt Hotel enthält: Hotelname, Hotel-Nr. und ein array von Zimmern
Objekt Zimmer enthält: Zimmer-Nr., Anzahl BettenAn "buche" wird übergeben ein Objekt "Kunde", die vom Kunden benötigte Anzahl Betten und jeweils Start- und Enddatum.
Nun war mein Grundgedanke, in der neuen Klasse per for-Schleife das Zimmer-array aus dem übergebenen Hotel zu durchlaufen und zu prüfen, ob zunächst einmal in einem Zimmer entsprechende Anzahl Betten verfügbar sind.
Allerdings existieren nur 1-2 Bettzimmer, es sollen also mehrere Zimmer gebucht werden, falls ein Kunde z.B. 7 Betten möchte.
Da weiss ich nicht so recht wie ich das prüfen soll.
Auch bekomme ich es nur hin, dass komplette Zimmer-array in ein neues array zu kopieren und dann durchzulaufen. Ich kann nicht das vorhanden Zimmerarray verarbeiten.Zsätzlich soll geprüft werden, ob die jeweiligen Zimmer in dem Buchungszeitraum verfügbar sind.
Das sollen wir mit Comparable<T> machen, das Problem würde ich aber gerne hinten anstellen, also zunächst einmal das prüfen auf verfügbare Zimmer/Betten und dann die Reservierung durchführen.Die erfolgreichen Reservierungen sollen dann in einen Container abgelegt werden.
Ich habe mittlerweilen so ziemlich alle Suchergebnisse von google durch, ich verstehe auch den Grundgedanken der abstrakten Klassen, allerdings sind die gegeben Beispiele meist zu simple (z.B. int-Variablen werden nur verarbeitet).
Ich hoffe jemand kann mir da ein paar Denkanstösse geben wie ich hier am besten vorgehe.
Hier mal mein bisheriger Ansatz, leider noch voller Probleme:public class Resvorgang extends Reservierungssystem { public Resvorgang(Hotel h) { super(h); } @Override public Reservierung buche(Kunde k, int anzBetten, Datum beginn, Datum ende) { //Hier nun prüfen ob in dem Hotel, die gewünschte Anzahl Betten verfügbar ist int i; int anzahl = getHotel().getZimmer_array().length; //wieviele Zimmer sind da Zimmer[] Zim_temp = new Zimmer[anzahl]; Reservierung[] Res_ablage = new Reservierung[anzahl]; //Test-array zum ablegen der Reservierungen, Größe: Zimmeranzahl Zim_temp = getHotel().getZimmer_array(); //temp-array um das Zimmerarray des Hotels zu holen //Nun per for-Schleife das zimmer-array durchgehen und checken ob Betten da sind for (i=0; i<anzahl; i++) { int akt_zimnr = Zim_temp[i].getZimmernr(); if (Zim_temp[i].getBetten() < anzBetten) return null; //wenn in dem aktuellen Zimmer nicht genug Betten, dann NULL zurück else Res_ablage[i] = new Reservierung(k, Zim_temp[i] , beginn, ende); //Reservierung für das aktuelle Zimmer durchführen } }
-
Hm deine Grundidee ist ja schonmal nicht schlecht.
Neben ein paar Syntax Fehlern hast du jedoch noch ein Logik-Problem mit deiner Schleife. Im Moment ist es so das die Funktion null zurück gibt sobald ein Zimmer gefunden wird, das weniger Betten hat, als benötigt werden. Wenn das erste Zimmer nicht genug freie Betten enthält liefert die Funktion also null obwohl die anderen Zimmer garnicht überprüft worden sind.Eine Sache ist mir bei der Aufgabenstellung allerdings noch nicht ganz klar. Es soll ja ein Objekt der Klasse Reservierung zurückgegeben werden. Ist die Klasse Reservierung schon vorgegeben oder hast du da noch freie Hand?
Denn wie du gesagt hast kann es ja vorkommen das mehrere Reservierungen durchgeführt werden müssen. Bezieht sich ein Reservierung-Objekt immer auf genau ein Zimmer oder können auch mehrere Zimmer mit einem Objekt reserviert werden? Wenn das nicht der Fall ist müsstest du eigentlich ein Array oder eine Liste mit Reservierungen zurückgeben.
-
Also vielen Dank für die Antwort. Die Klasse "Reservierung" haben wir in einer Aufgabe zuvor geschrieben und ist wie folgt definiert:
public class Reservierung { private Kunde kunde_res; private Zimmer zimmer_res; private Datum datum_beginn; private Datum datum_ende; private int res_nummer; private static int counter=0;
Die Klassen "Kunde, Zimmer, Datum" sind ebenfalls selbst geschrieben, relevant dürfte Zimmer sein, die hat als Attribute "Zimmernr. und Anzahl Betten"
Die Klasse Reservierung wird dabei im main so aufgerufen:
Reservierung default_reservierung = new Reservierung(testkunde, testzimmer, testbeginn, testende);
testkunde = Kunde
testzimmer = Zimmer
testbeginn/-ende = DatumIn der jetzigen Aufgabe sollen wir im Grunde genommen eine Klasse schreiben, welche den Reservierungsvorgang durchführt und zwar unter Berücksichtigung von:
- Verfügbarkeit eines Zimmer in dem gewünschten Zeitraum
- Anzahl der Betten in den freien Zimmern, ggf. mehrere Zimmer für einen Kunden buchenDabei ist die abstrakte Klasse "Reservierungssystem" vorgegeben. Ich bin zwischenzeitlich auch etwas weiter gekommen, allerdings ist irgendwie der Wurm drin, hier mal mein bisheriger code:
public class Resvorgang extends Reservierungssystem { public Resvorgang(Hotel h) { super(h); } @Override public Reservierung buche(Kunde k, int anzBetten, Datum beginn, Datum ende) { //Hier nun prüfen ob in dem Hotel, die gewünschte Anzahl Betten verfügbar ist int i; int anzahl = getHotel().getZimmer_array().length; //wieviele Zimmer sind da Zimmer[] Zim_temp = new Zimmer[anzahl]; Reservierung Res_ablage = new Reservierung(); //temp zum ablegen der Reservierung Zim_temp = getHotel().getZimmer_array(); //temp-array um das Zimmerarray des Hotels zu holen //Nun per for-Schleife das zimmer-array durchgehen und checken ob Betten da sind for (i=0; i<anzahl; i++) { if (Zim_temp[i].getBetten() < anzBetten) Res_ablage = null; //nicht genug Betten, dann NULL zurück if (Zim_temp[i].getBetten() >= anzBetten) { Res_ablage = new Reservierung (k, Zim_temp[i], beginn, ende); break; } } return Res_ablage; }
Übrigens ist die abstrake Klasse in 3 Methoden unterteilt (ich hoffe ich verwechsel keine Begriffe grad ):
public abstract class Reservierungssystem { private Hotel hotel; //Hotel, für welches die Reservierungen durchgeführt werden public Reservierungssystem (Hotel h) { hotel = h; } public Hotel getHotel() { return hotel; } /** bucht ein einzelnes Zimmer, @return die Reservierung, falls ein Zimmer gebucht werden konnte, sonst NULL */ public abstract Reservierung buche (Kunde k, int anzBetten, Datum beginn, Datum ende); /** bucht eine bestimmte Anzahl Zimmer, @return Menge mit Reservierungen */ public abstract Collection<Reservierung> buche (Kunde k, int anzZimmer, int anzBetten, Datum beginn, Datum ende); /** bucht ein bestimmtes Zimmer (gegeben durch Zimmernr) @return die Reservierung, sonst NULL */ public abstract Reservierung bucheZimmerNr (Kunde k, int zimmerNr, Datum beginn, Datum ende);
Die AUfgabe zielt darauf ab in einer geeigneten Containerklasse die Reservierungen abzulegen, zum vergleichen der Datumsangaben soll dann noch das Interface Comparable<T> eingebunden werden, damit ein Zimmer nicht doppelt belegt werden kann.
Ich glaube ich komme bei der Aufgabe erst dann weiter, wenn ich diese Container-Klasse fertig habe, dass ich zumindest alle Reservierungen dort ablegen kann. Dann hoffe ich, gibt es mehrere Möglichkeiten zur Laufzeit zu prüfen, ob ein Zimmer gebucht werden kann oder nicht.
Leider fehlen mir nun einfach die Ideen, wie ich das umsetze. Unser script/Dozent ist dabei leider auch keine große Hilfe, so dass ich auf diesem Wege immer nach Lösungen suche...
-
Ein Zimmer mit einer bestimmten Zimmer-Nummer zu buchen sollte das einfachste sein.
Müsste nach dieser Art funktionieren:/** bucht ein bestimmtes Zimmer (gegeben durch Zimmernr) @return die Reservierung, sonst NULL */ public Reservierung bucheZimmerNr (Kunde k, int zimmerNr, Datum beginn, Datum ende) { Zimmer[] zimmerArray = getHotel().getZimmer_array(); for (int i = 0; i < zimmerArray.length; i++) { if (zimmerArray[i].getZimmernr() == zimmerNr) { // Wir haben das Zimmer mit der entsprechenden Zimmernummer gefunden // und erstellen eine Reservierung return new Reservierung(k, zimmerArray[i], beginn, ende); } } // Wenn wir hier ankommen heißt das, dass es kein Zimmer mit dieser ZimmerNr gibt return null; }
Es fehlt halt noch die Abfrage ob das Zimmer zu diesem Zeitpunkt belegt ist.
Ein einzelnes Zimmer buchen ist recht ähnlich. Du durchsuchst das Array bis zu ein Zimmer findest das mindestens soviele Betten hat wie benötigt werden. Wenn du so ein Zimmer gefunden hast erstellst du eine Reservierung.
/** bucht ein einzelnes Zimmer, @return die Reservierung, falls ein Zimmer gebucht werden konnte, sonst NULL */ public Reservierung buche (Kunde k, int anzBetten, Datum beginn, Datum ende) { Zimmer[] zimmerArray = getHotel().getZimmer_array(); Zimmer zimmer = null; // Schleife die solange läuft bis entweder alle Zimmer überprüft sind oder bis ein Zimmer // mit der entsprechenden Bettenanzahl gefunden wurde. for (int i = 0; i < zimmerArray.length && zimmer == null; i++) { // Wenn zimmerArray[i] genug Betten hat haben wir ein passendes Zimmer gefunden haben // Hier muss später auch noch die Überprüfung, ob das Zimmer zu dem entsprechendem // Zeitpunkt frei ist, eingefügt werden if (zimmerArray[i].getBetten() >= anzBetten) { zimmer = zimmerArray[i]; } } // Wenn zimmer an dieser Stelle immernoch null ist heißt das, dass es kein // Zimmer mit soviel Betten gibt. if (zimmer == null) { return null; } // Wenn zimmer nicht null ist geben wir die Reservierung zurück return new Reservierung(k, zimmer, beginn, ende); }
Die zimmer Variable wäre nicht unbedingt nötig, macht die Sache aber einfacher zu lesen finde ich.
Mehrere Zimmer zu reservieren funktioniert nach dem selben Prinzip. Nur musst du jetzt zusätzlich in der Schleife die freien Zimmer zählen und erst wenn du genug freie Zimmer gefunden hast die Reservierungen erstellen.
mfg xorm :xmas2:
-
Hi und danke soweit, habe das mal getestet, allerdings ist irgendwo noch ein Fehler.
Ich habe im Hauptprogramm 3 Reservierungen mal vorgenommen:System.out.println(new Resvorgang(mein_hotel).buche(kunde1, 1, beginn1, ende1)); System.out.println(new Resvorgang(mein_hotel).buche(kunde2, 2, beginn2, ende1)); System.out.println(new Resvorgang(mein_hotel).buche(kunde3, 2, beginn2, ende2));
Die Kunden und Start-/Enddatum habe ich vorher definiert. Der zweite Wert entspricht der Anzahl Betten die benötigt werden.
Das Zimmer-array sieht wie folgt aus:public Hotel(String hotelname, int hotelnr, int zimmer_anzahl) { super(); this.hotelname = hotelname; this.hotelnr = hotelnr; setZimmer_array(new Zimmer[zimmer_anzahl]); for (int i=0; i<getZimmer_array().length/3; i++) { getZimmer_array()[i] = new Zimmer (9000+i, 1); } for (int j=getZimmer_array().length/3; j<getZimmer_array().length; j++) { getZimmer_array()[j] = new Zimmer (9000+j, 2); }
Ich habe 5 Zimmer eingerichtet, ergibt:
Zimmer 9000 = 1 Bett-Zimmer
Zimmer 9001 - 9004 = 2 Bett-ZimmerWenn ich nun die Reservierungen durchführe, so bekommt der kunde1 das letzte Zimmer zugewiesen (obwohl er nur 1 Bett benötigt, also das erste Zimmer okay wäre) und die anderen beiden Kunden bekommen "null geliefert".
Problem ist ja, dass in der Schleife der Wert für zimmer nach jedem Durchlauf überschrieben wird, somit immer bis zum Ende durchläuft (sofern die Anzahl Betten reinpasst).
Wenn ich jeden Kunden 2 Bett-Zimmer buchen möchte, wird bei allen "null" geliefert.
Auch der Zähler, welcher bei jeder Reservierung inkrementiert wird, zählt in 5er Schritten hoch.
Also irgendwie kommt die Schleife nicht ganz klar...
-
Habs gefunden, so gehts:
public Reservierung buche(Kunde k, int anzBetten, Datum beginn, Datum ende) { Zimmer[] zimmer_array = getHotel().getZimmer_array(); Zimmer zimmer = null; Reservierung res_temp = null; //Nun per for-Schleife das zimmer-array durchgehen und checken ob Betten da sind for (int i=0; i<zimmer_array.length; i++) { if (zimmer_array[i].getBetten() >= anzBetten) { zimmer = zimmer_array[i]; res_temp = new Reservierung (k, zimmer, beginn, ende); break; } } return res_temp; }
Nun wäre noch interessant, wie ich jede durchgeführte Reservierung in einen Container ablegen kann und bei einer neuen Reservierung diesen Container prüfe, ob eine gewisse Zimmer-Nr bereit reserviert wurde.
Vielleicht kann da jemand ein kleinen Beispiel-code liefern ?
Gruss,
Lalas
-
lalas schrieb:
Problem ist ja, dass in der Schleife der Wert für zimmer nach jedem Durchlauf überschrieben wird, somit immer bis zum Ende durchläuft (sofern die Anzahl Betten reinpasst).
Hm kurze Frage dazu: Hast du gesehen das ich in der Schleife die Bedingung "i < zimmerArray.length && zimmer == null;" verwendet habe?
Durch die Abfrage "zimmer == null" sollte die Schleife eigentlich verlassen werden sobald das erste Zimmer gefunden wurde.Zu den Containern. Da deine Methode eine Collection zurück gibt hast du die freie Auswahl was du für einen Container verwenden willst. Collection ist so eine Art Basis-Interface für jeden Container. Mehr dazu hier und hier
Am einfachsten wäre in deinem Fall wahrscheinlich eine einfache Liste.
Zum Beispiel so:// Liste anlegen ArrayList<Reservierung> liste = new ArrayList<Reservierung>(); // 2 Reservierungen hinzufügen liste.add(new Reservierung(..)); liste.add(new Reservierung(..)); // Alle Elemente der Liste durchlaufen for (int i = 0; i < liste.size(); i++) { Reservierung r = liste.get(i); // hier irgendwas mir r machen.. }
Da ArrayList das Interface List implementiert was wiederrum von Collection abgeleitet ist kannst du in deiner Funktion ohne Probleme eine ArrayList zurückgeben.
mfg xorm :xmas2:
-
Guten Morgen,
ich sitze noch an meiner Semesteraufgabe und hänge immer noch ein wenig...
Ich habe eine ArrayList erzeugt welche mehrere Objekte vom Typ "Reservierung" enthält.
Dabei enthält "Reservierung" unter anderem das Attribut "Datum". Dies besteht wiederrum aus "Jahr" "Monat" "Tag" und wird als string abgelegt.Wenn nun eine Reservierung durchgeführt werden soll, muss zuvor in der ArrayList nachgeschaut werden, ob irgendeine Reservierung bereits vorhanden ist, welche in dem gewünschten Reservierungszeitraum passt.
Die Werte Tag/Monat/Jahr liegen in der Klasse Datum jeweils als int vor.Nun ist die Vorgabe allerdings, das wir das Interface Comparable<T> in unsere Klasse "Datum" und weiteren Klassen implementieren um den Vergleich anzustellen.
Nun weiss ich nicht so recht wie ich das anstelle, hier mal mein code (auszugsweise);
public ArrayList<Reservierung> buche2(Kunde k, int anzZimmer, int anzBetten, Datum beginn, Datum ende) { Zimmer[] zimmer_array = getHotel().getZimmer_array(); Zimmer zimmer = null; Reservierung res_temp = null; ArrayList<Reservierung> res_liste = new ArrayList<Reservierung>(); for (int i=0; i<=anzZimmer; i++) { if (zimmer_array[i].getBetten() >= anzBetten) { zimmer = zimmer_array[i]; res_temp = new Reservierung (k, zimmer, beginn, ende); res_liste.add(res_temp); } } return res_liste; }
und die Klasse Datum (getter/setter usw lass ich mal weg):
public Datum(int tag, int monat, int jahr) { super(); this.tag = tag; this.monat = monat; this.jahr = jahr; }
Nun muss ich ja irgendwie bei meiner Reservierung eine Abfrage einbauen, ob das Startdatum/Enddatum des aktuelle Zimmer (welche per Schleife durchlaufen werden), kleiner/größer/gleich ist als das gewünschte Reservierungsdatum.
Vielleicht hat da jemand einen Vorschlag wie ich das am besten einbaue
Gruss,
Lalas
-
*schieb*
Wäre nett wenn jemand mir hier einen Tipp geben kann.
Es geht im wesentlichen um ein konkretes Beispiel, wie ich Comparable<T> verwenden kann.
Gruss,
Lalas