Café International Theoriensammlung

Du musst dringend Objekt-orientiert denken. Nicht die Infos des Gastes sondern der Gast selber soll gespeichert werden. Und ob ein Gast dort sitzt prüfst du einfach mit “if(this.guest == null)”. Und an den Tisch kannst du auch wieder das Gast-Objekt weitergeben und erst dort die benötigten Informationen aus dem Gast raussuchen. So hast du eine Abbildung der realen Welt objekt orientiert umgesetzt.

Nein ist es nicht. Weil ob ein Stuhl belegt ist, siehst du indem du prüfst ob die gastkarte == null ist.

Einen Stuhl legst du an, indem du ihm direkt einen Tisch zuweist. Das ist das einzige was zu Anfang klar ist.

Du brauchst mE auch eine Tisch m:n Stuhl beziehung. Sprich im Stuhl ein Feld für alle Tische denen er angehört. Gleichzeitig auch pro Tisch eine Liste mit allen Stühlen.

die Belegt-Variable brauchst du auf natürliche Weise nicht:
wenn die Gast(karte) gespeichert ist, eine Methode kann prüfen ob jene Variable != null ist -> boolean, fertig,
wie ja auch schon (direkt zuletzt) gesagt wurde…

kann man eigentlich auch Gast statt Gastkarte sagen, die Klasse so nennen? wäre ja viel kürzer…

ob man das Gast-Objekt oder dessen Info-Bestandteile ablegt ist für die Lösung letztlich evtl. gleichwertig,
mit Objekt aber einfacher,

  • spart die Einzelvariablen, die ja vom Objekt abfragbar sind
  • vermeidet Fehler wie ein String gesetzt, der andere fehlend (warum auch immer)
  • ermöglicht evtl. beim Abräumen schnellen Zugriff auf den Gast, falls benötigt, diese Karte aus Listen aktueller Karten entfernen oder was auch immer

sofern der Stuhl nicht seine bis zu drei Tische für Abfragen braucht, kann es bei diesem Stand auch bleiben,
wichtig ist dass mehrere Tische auf exakt denselben Stuhl verweisen, dafür schon Objekt wichtig genug und Hauptaufgabe erfüllt

Die Referenzen auf die Stühle musst Du ja irgendwo halten. z.B. in einer Liste.
Zum Rest wurde eigentlich alles gesagt.
Hier mal ein KSKB zu Gast, Stuhl und besetzt. Vielleicht wird manches dadurch klarer:

[SPOILER]```import java.util.ArrayList;
import java.util.List;

public class CafeInternational {
public static void main(String s) {
new CafeInternational().startDemo();
}

public void startDemo() {
	List<Seat> seats = new ArrayList<Seat>();
	for (int i = 0; i < 5; i++)
		seats.add(new Seat());
	
	seats.get(1).takePlace(new Guest(Nation.ITALIAN, Gender.MALE));
	seats.get(2).takePlace(new Guest(Nation.GERMAN, Gender.FEMALE));
	seats.get(4).takePlace(new Guest(Nation.ITALIAN, Gender.FEMALE));
	
	for (int i = 0; i < seats.size(); i++) {
		Seat seat = seats.get(i);
		if (seat.isOccupied()) {
			System.out.println(String.format("Stuhl Nr. %s ist besetzt durch : %s.", i, seat.getGuest()));
		}
		else {
			System.out.println("Stuhl " + i + " ist noch frei.");
		}
	}
}

class Guest {
	private Nation nation;
	private Gender gender;

	public Guest(Nation nation, Gender gender) {
		this.nation = nation;
		this.gender = gender;
	}

	public String toString() {
		return "Gast [nation=" + nation + ", gender=" + gender + "]";
	}
}

class Seat {
	private Guest guest;

	public void takePlace(Guest guest) {
		this.guest = guest;
	}

	public boolean isOccupied() {
		return guest != null;
	}

	public Guest getGuest() {
		return guest;
	}
}

enum Nation {
	GERMAN, ITALIAN
}

enum Gender {
	MALE, FEMALE
}

}```[/SPOILER]

[QUOTE=timbeau]Nein ist es nicht. Weil ob ein Stuhl belegt ist, siehst du indem du prüfst ob die gastkarte == null ist.

Einen Stuhl legst du an, indem du ihm direkt einen Tisch zuweist. Das ist das einzige was zu Anfang klar ist.

Du brauchst mE auch eine Tisch m:n Stuhl beziehung. Sprich im Stuhl ein Feld für alle Tische denen er angehört. Gleichzeitig auch pro Tisch eine Liste mit allen Stühlen.[/QUOTE]
Hallöle,

ich hab mich mal daran versucht das ganze so zu bauen und möchte nun einmal eine objektive Meinung haben, ob das Mumpitz ist oder seriös aussieht. :wink:
Also, meine Klasse Stuhl sieht nun so aus:


import java.util.List;

public class Stuhl {
	
		Gastkarte gast;
		public List<Tisch> tische;
		
		public Stuhl(List<Tisch> tischnamen)
		{
		    this.tische = tischnamen;
		}
}

Die Tisch-Klasse hat folgenden Inhalt:

import java.util.List;

public class Tisch {
	
	public List<Stuhl> stuehle;
	public Tisch(List<Stuhl> stuhlnamen) {
		this.stuehle = stuhlnamen;
	}
	

}

Ich generiere nun hiermit beispielsweise Tische und Stühle:

		 Stuhl stuhl2 = new Stuhl(Arrays.asList(tische.get(3),tische.get(4)));
		 Stuhl stuhl3 = new Stuhl(Arrays.asList(tische.get(2),tische.get(3)));
		 Tisch tisch1 = new Tisch(Arrays.asList(stuehle.get(3),stuehle.get(0)));```
Die Nummern seien mal dahingestellt, frei erfunden, wenn das dann läuft, nummere ich die richtig. ;)

So nebenbei: Diese beiden Listen hier, die noch von Belang sind existieren.
```protected static List<Tisch> tische = new ArrayList<Tisch>();
  protected static List<Stuhl> stuehle = new ArrayList<Stuhl>();```

Vielen Dank an alle, die mich bis hierhin ausgehalten haben.

Gruß
Lukas

Oh, _Michael, sorry, ich seh immer nicht, wenn ein Beitrag dazwischenrutscht, der geschrieben wurde, während ich meinen Beitrag schreibe.
Vielen Dank dafür Deinen Beitrag, ich schaue ihn gleich einmal an und gehe später darauf ein.
  Stuhl stuhl2 = new Stuhl(Arrays.asList(tische.get(3),tische.get(4)));
  Stuhl stuhl3 = new Stuhl(Arrays.asList(tische.get(2),tische.get(3)));
  Tisch tisch1 = new Tisch(Arrays.asList(stuehle.get(3),stuehle.get(0)));

man kann die Welt nicht mit einem Atemzug aufbauen,
Stuhl-Konstruktor braucht fertige Tische, Tisch-Konstruktor braucht fertige Stühle = Konflikt,
ich weiß nicht was du dazu vorhast, aber kann nicht gut enden

für Stühle und Listen bieten sich sowieso Enums an, da begrenzt,
aber gehe auf jeden Fall so vor:
Stühle in Enum simpel setzen oder in drei Zeilen eine Liste von 0-n erzeugen, keine individuellen Infos im Konstruktor, Massenware

die Tische dann aufbauen:

  Tisch tisch1 = new Tisch(stuehle,3,0);

idealerweise mit Varargs-Parameter statt Arrays.asList(), oder wie auch immer reicht jedenfalls Liste/ Array der Indexe,
dazu die Stuhl-Liste einmalig übergeben, falls nicht Enum,
evtl. auch eine create-Methode statt Konstruktor, na wird zuviel

wichtig bei der ganzen Sache jedenfalls:
im Tisch-Konstruktor oder wo auch immer, da wo die Stühle einzeln oder als Liste dem Tisch zugeordnet werden,
da auch diesen Stühlen jeweils den Tisch hinzufügen

so sparst du dir für die Stühle die komplette evtl. nicht passende nochmalige Auflistung der Verknüpfungen,
ein wichtiges Mittel allgemein: wenn A zu B zugeordnet wird auch B zu A hinzu, an einer Code-Stelle

(im Falle von Enums könnte man in diesem Fall bemängeln, dass die Enum-Werte von außen verändert werden)

tatsächlich aufgeschrieben sehen so viele Stühle in einer Enum doch nicht so gut aus,
statt solcher Benennung …1, …2, …3 nimmt man ja lieber Listen,

aber die Enum-Werte direkt wird man im weiteren Programm eh nicht ansprechen,
die Objekte mehr in Listen durchlaufen oder über Variablen ansprechen, schlimm auch nicht unbedingt


was nun auf gar keinen Fall geht ist, die Enum mehrfach zu definieren, das widerspricht ja aller Logik, allen Zwecken (eben nur EINE Stelle zu haben),
wahrscheinlich mein Fehler, komplizierte Enum hineinzubringen,

aber selbst wenn du nur die Klassen an sich hast und Objekte erzeugst, wie auch Gast(karten),
dann passt du doch hoffentlich darauf auf, dass die 100 Gastkarten nur 1x im Programm angelegt werden, nicht Stuhl eigene 100, und Tisch auch nochmal eigene 100 usw…

es darf nur 1x 100 Karten geben, 1x 24 Stühle, 1x 12 Tische, soviel sollte doch als Grundlage klar sein,
ich gehe positiv ausgelegt davon aus dass du das eh wolltest, dich nur in der Syntax verheddert hast, insbesondere Enum,
aber

  Stuhl stuhl2 = new Stuhl(Arrays.asList(tische.get(3),tische.get(4)));
  Stuhl stuhl3 = new Stuhl(Arrays.asList(tische.get(2),tische.get(3)));
  Tisch tisch1 = new Tisch(Arrays.asList(stuehle.get(3),stuehle.get(0)));

sah ja früher auch schon verdächtig aus -> “was ist in den Listen tische + stuhle wenn du gerade erst stuhl1 + tisch1 definierst?”

wenn es die Enums gibt, dann sind das die TopLevel-Klassen,
dann lohnt es sich nicht (bzw. kontraproduktiv) dazu noch Klassen Stuhl + Tisch zu haben,
übrigens immer alles in Einzahl benennen,

egal ob Enums oder Klasse, einmalig 24 und 12 und keine weiteren Objekte benötigt, intern noch verlinken,
nicht in jeder Klasse neu, keine globalen Listen die dasselbe wie lokal neue Objekte enthalten und all dieser Kauderwelsch,

ein einziger Ort in der ganzen Java-Welt für Stuhl, davon 24, und Ende dazu, polter polter,

wenn dann Probleme, dann kann man sie lösen,
wie gesagt ist Verlinkung im Konstruktor nicht direkt möglich, Henne-Ei-Problem,
aber deswegen nicht auf komische Konstrukte kommen,
man kann immer erst simple leere Objekte erstellen und sie danach dann einander zuweisen

In der Syntax verheddert, Schock, ist uns allen das nicht schon seit Anbeginn dieses Themas klar? :frowning:

Ich lege die Objekte in der Tat immer nur einmal an, das hab ich wenigstens schon auf die Reihe bekommen.
Wenn ich irgendwann mal irgendwie Code zusammengebastelt habe, der die Stühle generiert, dann rufe ich diesen doch auch nur einmal auf. :wink:
In der Hauptklasse arbeite ich am Anfang einfach alles ab, was am Anfang benötigt wird, das generieren der Stühle und Tische kommt eben in eine Methode und wird einmal aufgerufen.

Ich muss mich die Tage nur irgendwie auseinandersetzen, wie ich den Quatsch seriös generiere. Der bisherige Code ist Käse. Auch wenn ich großer Fan von Käse bin.

Schöne Grüße
Lukas

du magst ja mit dieser Sache dich und das Forum gut beschäftigen, aber nützlich ist dieses Vorgehen nicht,
wild unbekannten Code auszuprobieren, komplizierte Varianten halb zu posten oder Detailfehler davon dann anzusprechen, das bringt niemanden voran

gut dass du vorher nur Gastkarten für sich hattest, schwierig genug,
das mit dem anderen gemischt wäre ja auch nicht mehr aufzuknoten gewesen

aktuell wäre ein vermeintlich simpler aber dann doch günstiger Anfang, auf beliebige Weise einfach nur 12 Tische zu erzeugen,
sie ordentlich irgendwo ablegen (falls nicht EINE Enum, dann durchaus irgendwo EINE Liste)
und der Reihe nach mit System.out.println() auszugeben
“tisch1”
“tisch2”
“tisch3”
usw.
um etwas mehr Durchblick zu haben kannst du sie ja noch mit einem zusätzlichen String beschreibung versorgen und darin “NordOst” oder so hineinschreiben

simpel, aber ein Meilenstein,
danach für den Rest aller Zeiten darauf aufpassen, das keine neunmalkluge Stuhl-Klasse oder sonstiger Code auf einmal noch neue Tische erzeugt,
das hat nun nichts mit Syntax zu tun sondern mit aufpassen

Tisch tisch1 = new Tisch(Arrays.asList(stuehle.get(3),stuehle.get(0))); // hmm, tisch1? ich hab doch schon eine tische-Liste, Abbruch Abbruch!!!

Ich verstehe Dein Belangen.
Entschuldigt, wenn ich hier manchmal etwas unklug auftrete, ich zwinge niemanden mir zu helfen, freue mich jedoch immer, wenn jemand kluge Ideen hat.

Das mit dem Doppelt generieren verstehe ich nun, ja das ist in der Tat inkorrekt. Ich hatte nur bisher keine Ahnung, wie ich das anders machen sollte.
Ich muss mich die Tage mal an den Quatsch ransetzen, wie ich das programmiere, mal gucken.
Wenn nicht gebe ich eben nen Stein-Schere-Papier-Projekt ab, bin anscheinend zu doof für Java.

Schönen Montag euch allen!
Lukas :slight_smile:

[quote=FranzFerdinand]Ach, langsam glaube ich, ich sollte Java bleiben lassen, ich versteh den Quatsch einfach nicht.[/quote]Oder wie es im „kleinen Arschloch“ heist:

Selbstmord? Aber ja, dass ist natürlich auch eine Lösung.

IMHO ist das Stühle/Tische-enum keine sinnvolle Lösung. Es ist ja nachher nicht notwending einen bestimmten Stuhl/Tisch zu identifizieren.

Das von @SlaterB angesprochene Henne-Ei-Problem kann man in den Griff bekommen, wenn man die Stühle sich bei „ihren“ Tischen registrieren lässt (die Tisch-Klasse also eine addStuhl()-Methode bekommt). Im wahren Leben ist es ja auch so, dass man erst die Tische hin stellt, und dann Stühle dazu.

bye
TT

[quote=FranzFerdinand]“Der Konstruktor Tisch(Laenderkarte) ist nicht definiert.”
Das ist richtig. Aber ich fische doch aus der Laenderkartenliste die Elemente, die zufällig auch dem Land entsprechen, wie ich es beim Tisch definiert habe: public final Land land;

Kann das einer erläutern? Danke![/quote]
In kurz?
Der Computer mach dass, was Du ihm sagst, nicht dass was Du willst.

in lang:
Java ist stark typisiert. Das heist, dass das an den Konstruktor übergebene Onjekt auch von dem Typ (oder einem seiner Erben) sein muss, der im Konstruktor deklariert ist.
Die Klasse Laenderkarte erbt aber (zu recht) nicht von Land.
Du hast 2 Möglichkeiten:[ol][li]Du änderst tische.add(new Tisch(laenderkarten.get(n)));zutische.add(new Tisch(laenderkarten.get(n).getLand()));
[/li][li]Du änderst den Type des Parameters im Konstruktor von Tisch und des Feldes, dass ihn aufnimmt von Land nach Laenderkarte.[/ol]
[/li]bye
TT

Meiner Meinung ist die Klasse Laenderkarte überflüssig und bietet keinen Mehrwert, für Deinen kannst doch direkt Land Objekte nehmen. Für den Tisch würde ich ohnehin direkt das enum Land nehmen, da Du damit ja immer vergleichen musst, wenn sich ein Gast setzen will.

Jeder Tisch hat eine Liste von Stühlen.

	
	private List<Stuhl> stuehle = new ArrayList<Stuhl>();
	
	public void addStuhl(Stuhl stuhl){
		if(stuehle.size() == 4){
			System.err.println("Kein Platz mehr fuer weitere Stuehle");
		} else {
			stuehle.add(stuhl);
		}
	}

}

Jeder Stuhl kennt den Tisch an den er gesetzt wird.

	
	private Gast gast;
	
	private Tisch tisch;
	
	public void addToTisch(Tisch tisch){
		this.tisch = tisch;
	}
	
	public void addGast(Gast gast){
		if(gast == null){
			this.gast = gast;
		} else {
			System.err.println("Stuhl schon besetzt");
		}
	}

}```

[quote=timbeau]public void addGast(Gast gast){ if(gast == null){ this.gast = gast; } else { System.err.println("Stuhl schon besetzt"); } }[/quote]
der Teufel liegt im Detail, Vorsicht :wink:

Ohman , shame on me.

Die Zeile mit der Abfrage ob der Stuhl schon von einem Gast belegt ist, muss natürlich „if(this.gast == null)“ heißen.

Ich bin einfach zu lange raus aus der Programmierung :frowning:

Naiver weise könnte man jetzt noch meckern, dass man mit der Methode den Gast nicht mehr auf null setzten kann.
Ich sage aber, dass man dazu sowieso besser eine Methode removeGast() schreiben sollte.

bye
TT

[QUOTE=timbeau]Jeder Tisch hat eine Liste von Stühlen.

	
	private List<Stuhl> stuehle = new ArrayList<Stuhl>();
	
	public void addStuhl(Stuhl stuhl){
		if(stuehle.size() == 4){
			System.err.println("Kein Platz mehr fuer weitere Stuehle");
		} else {
			stuehle.add(stuhl);
		}
	}

}

Jeder Stuhl kennt den Tisch an den er gesetzt wird.

	
	private Gast gast;
	
	private Tisch tisch;
	
	public void addToTisch(Tisch tisch){
		this.tisch = tisch;
	}
	
	public void addGast(Gast gast){
		if(gast == null){
			this.gast = gast;
		} else {
			System.err.println("Stuhl schon besetzt");
		}
	}

}```[/QUOTE]

Dem Namen nach würde ich von der `Stuhl#addToTisch()` Methode intuitiv erwarten, dass sie `Tisch#addStuhl()` aufruft.

@Crian : Das sehe ICH etwas anders. Hier würde ich in einer übergeordneten Klasse eher etwas in der Art “setzeStuhlUndTisch” oder “composeChairToTable” und dort beides aufrufen.

was ich vielleicht zuvor schon erstmals ins Spiel gebracht habe kann auch wirklich gefährlich sein, etwa wenn
Tisch#addStuhl() bereits manuell aufgerufen wurde,
dann kommt Stuhl#addToTisch() mit zweitem Mal Tisch#addStuhl(), doppelten Hinzufügen…

allerdings auch bisschen irrsinnig wie viele hier zu diesem Programm mit überschaubarer Weltbedeutung schreiben :wink: