OOP Setter u. Getter (und weiteres)

Leo123

Mitglied
Hallöchen liebe Community,
wir haben im letzten Semester Java gelernt und mir sind seitdem einige Fragen
offen geblieben. In den Semesterferien habe ich mich jetzt ziemlich intensiv mit
Java beschäftigt (ob das jetzt sehr produktiv war.. darüber lässt sich streiten :bae: ).

Um das Gelernte umzusetzen, wollte ich mich an einem kleinem Spielchen versuchen.
Allerdings glaube ich, dass ich mich ziemlich bescheuert dabei anstelle und würde gerne
mal Rat von erfahrenen Java-Programmierern hören ;-)

Spielidee (einen kleinen Siederclone - nur einen kleinen Simulator):

Paketstruktur:
src:

  • lager (Lager.java)
  • resources (Resources.java,Rohstoffe.java,Truppen.java)
  • rohstoffe (Stein.java,Holz.java....)
  • truppen (Speerkämpfer.java,Axtkämpfer.java.....)
  • gui (Hauptprogramm.java, Gui_Rohstoffe.java, Gui_Truppen.java....)

Wir haben einiges mit OOP bereits gemacht und wollte möglichst viel mit Generics und Codewiederverwendung umsetzen. (allerdings bin ich ziemlich verwirrt).
Ich habe jetzt häufiger gelesen, dass Getter-und Setter nicht so häufig verwendet werden
sollen usw. Zwischenzeitlich habe ich für jeden Rohstoff ein Singleton erstellt, den ich mit
getinstance() verändert habe. (eigentlich Quatsch, weil das Entwurfsmuster eher für GUI verwendet wird? Oder nicht?) - Wie würde man geschickt vorgehen?

Beispiel:
(meine Versuche)
1. Wenn ein Button in der GUI gedrückt wird, wird ein neues Rohstoff-Holz-Object erstellt und dann
das neue mit dem alten addiert. (altes Holz Objekt(Menge) + neues Holz Object(Menge)

2. Wenn ein Button gedrückt wird, wird getInstance() aufgerufen, wenn das Objekt noch nicht
besteht, wird eins erzeugt. Wenn bereits eins vorhanden ist, wird die Holzmenge dazuaddiert.

3. Wenn ein Button gedrückt wird, einfach den Setter von dem Holzobjekt aufrufen und den alten
Wert mit dem neuen Wert addieren.

4. ...


So habe ich es momentan gemacht:
Resources.java
Java:
public abstract class Resources {
}

Java:
package resources;

public abstract class Rohstoffe extends Resources{
	
	private final String name;
	private int value;
	private int price;
	
	public Rohstoffe(String name,int value,int price){
		this.name=name;
		this.value=value;
		this.price=price;		
	}

	@Override
	public String toString() {
		return "Rohstoffe [name=" + name + ", value=" + value + ", price="
				+ price + "]";
	}

	public int getValue() {
		return value;
	}
}

Java:
public class Stein extends Rohstoffe{
	private  static final String name="STONE";
	private  int value=20;
	private  static int price=30;
	
	public Stein(int value)
	{
		super(name,value,price);
	}
}


Java:
public class Lager<T> {
	private T resources;

	public boolean isEmpty() {
		return this.resources == null;
	}

	public void fill(T resources) {
		if (this.resources != null) {
			throw new IllegalStateException();
		}
		this.resources = resources;
	}

	public T empty() {
		if (this.resources == null) {
			throw new IllegalStateException();
		}
		T resources = this.resources;
		this.resources = null;
		return resources;
	}

	public String toString() {
		return this.getClass().getName() + "[resources=" + this.resources + "]";
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// Lager<Rohstoffe<?>> rohstofflager=new Lager<Rohstoffe<?>>();

		// Wood wood1=new Wood();

		// rohstofflager.fill(new Wood());
		// rohstofflager.fill(wood1);
		// rohstofflager.fill(stein1);

		// System.out.println(rohstofflager);

		// wood1.setPrice(30);

		// System.out.println(rohstofflager);

		Lager<Stein> stone = new Lager<Stein>();
		stone.fill(new Stein(2));
		System.out.println(stone);
	}

}

Hier ein kleines Testbild ;-)
Directupload.net - 7mqeqi62.png

Würde man jedes mal, wenn die Holzanzahl sich verändert den Konstruktor vom Holz aufrufen?
Oder das Objekt verändern? Ich hatte vor, ein Lager von Typ T anzulegen, in das man
dann nur Rohstoffe vom Typ Rohstoffe mit dem Untertyp Holz,Stein einlegen kann.
Und dann ein Lager wo man nur Truppen vom Typ Bogenschützen usw einlagern kann.

Was wäre ein guter Programmierstil? Ich hoffe ihr könnt mir Tipps und Tricks geben. Hab einige Javabücher in der Unibibliothek durchgeackert.. aber irgendwie würde ich das gerne an meinem Beispiel lernen :toll:
Vielen Dank an alle, die sich das durchgelesen haben :D
Gruß
Leo
 
Zuletzt bearbeitet:

anti-held

Bekanntes Mitglied
Also ich würde die Klasse Resources weglassen. Denn für mich sollten Truppen und Resourcen nicht in einen Hut gesteckt werden.
Bei deinem Lager kannst du für das Template T auch die abstrakte Klasse Rohstoffe verwenden. ( mit <T extends Rohstoffe>)
So ist garantiert, dass keiner z.B. einen String einfügt.
Im Lager selbst würde ich dann statt diesen Methoden eher welche wie [c]boolean add(T rohstoff)[/c] und [c]T sub(int value)[/c] machen. So kannst du mehrere Steine in deinem Lager halten. Auch kannst du wenn du später für Gebäude Rohstoffe brauchst, einfach Steine im Wert eines bestimmten values abziehen.
Der boolean Rückgabewert bei der add Methode kann zurückgeben, ob das Lager bereits voll ist.
Im Lager sollte so eine Membervariable sein, die den maximalen Value angibt. (Also Lagergröße)
 

Leo123

Mitglied
Vielen Dank für die Antwort!
Die Klasse Resources habe ich nun rausgelöscht.
Hab gerade versucht dein Tipp umzusetzten, allerdings stehe ich mal wieder auf dem Schlauch :rtfm:

Ich würde also add(T rohstoffe) aufrufen dann mittels add_Rohstoff(T rohstoffe) überprüfen
ob das Lager schon voll ist. Wenn dabei True rauskommt, wird der Rohstoff hinzugefügt.

Ich habe noch ein paar Denkfehler in der Methode add_Rohstoff.
Wie kann ich prüfen, ob der übergebene Rohstoff vom Typ Wood oder Stein ist?
Daran bin ich jetzt schon häufiger hängen geblieben. Das Zauberwort heißt soweit ich
weiß instanceof..
if(rohstoffe instanceof Wood) <-- so geht das leider nicht :(


Java:
public class Lager<T extends Rohstoffe>{
	private T rohstoffe;
		
	private int max_holz=1000;
	private int max_stein=1000;
	
	private int cur_holz=0;
	private int cur_stein=0;
	
	private boolean add_Rohstoff(T rohstoffe)
	{
		if(cur_holz+rohstoffe.getValue() < max_holz || cur_stein+ rohstoffe.getValue() < max_stein)
		{
			System.out.println("Rohstoff kann eingelagert werden");
			return true;
		}
		else
		{
			System.out.println("Lager leider voll");
			return false;	
		}		
	}
	
	private T add(T rohstoffe)
	{
		if(add_Rohstoff(rohstoffe)==true)
		{
			if(rohstoffe instanceof Wood)
			{
				cur_holz=cur_holz+rohstoffe.getValue();
			}
			else if(rohstoffe instanceof Stein)
			{
				cur_stein=cur_stein+rohstoffe.getValue();
			}
			
		}
		else
		{
			System.out.println("Hups - Lager voll");
		}
		return rohstoffe;		
	}
	
	private T sub(int value)
	{
		return rohstoffe;		
	}
	
	public String toString()
	{
		return this.getClass().getName() + "[resources=" + this.rohstoffe + "]";
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		
		//Lager<Stein> stone=new Lager<Stein>();
		//stone.fill(new Stein(2));
		//System.out.println(stone);

	}

}
 

ARadauer

Top Contributor
Singleton solltes du gar nciht verwenden und wenn dann für Services.

Im Grunde sagt mir die Verwendung von instanceof das da in deinem Design was schief läuft.
Ist dein Rohstoff jetzt ein Objekt das zu in einer Liste hälst oder nutzt du es nur um zu erkennen was du hinzufügst?
Was willst du mit dem Objekt machen?
 

Leo123

Mitglied
Danke - schon wieder was dazugelernt!
Das Problem mit der Anwendung von Objekten ist meine Frage ;-) Wie man das am besten umsetzten würde.
In der Uni wurden uns nur gezeigt, was es alles gibt und wie man das anwendet. Allerdings wurde
der Praxisbezug etwas vernachlässigt (so kam es mir jedenfalls vor ;-) )
Wir hatten z.B als Aufgabe ein Zugverwaltungsprogramm zu schreiben, bei dem es
möglich war mit new Zug("Name",100,29....) einen neuen Zug zu erstellen,
oder mit Hilfe von Gettern- und Settern Werte zu verändern.

In unseren Vorlesungsfolien steht, dass es nur die einfachste Möglichkeit ist,
auf Objektvariablen zuzugreifen und das intensiver Gebrauch von
Getter- und Setter-Methoden kein Zeichen von Objektorientierung ist.
Und da z.B meine Holzfäller alle 5 Sekunden (nur als Beispiel) Holz dazu geben sollen,
wäre das ein intensiver Gebrauch (denke ich ;-) )

Momentan habe ich mir vorgestellt, dass ich in der Main oder wenn man einen Button
drückt z.B new Stein(2) aufgerufen wird. (zum Erzeugen von 2 Steinen)
und dieser dann zu den anderen Steinen im Lager, hinzugefügt wird.

Und für das Lager habe ich mir die Verwendung von Generics überlegt,
damit man z.B Holz und Steine hinzufügen kann, Truppen allerdings nur in
ein anderes darf.

Allerdings habt ihr mehr Erfahrung und mich würden echt eure Möglichkeiten interessieren. :)
 

Mojo32

Mitglied
Hallo,

ich würde beim Lager Generics komplett weg lassen. Da wenn das Projekt größer wird und die Klasse Lager noch paar Funktionen hinzu bekommt keine Sau mehr durch blickt. Und wenn zu Steinen und Holz noch Lehm, Eisen, Gold, ..... hinzukommt wird die If-Anweisung im Lager irgendwann riesig groß.
Und wenn du jetzt ein Lager mit Steinen anlegst, dann hat dieses die Anzahl an Holz und Stein drin, was ich auch ungünstig finde.

Ich würde da eher Interfaces oder abstrakte Klassen verwenden. Zum Beispiel:

Lager (abstract)
SteinLager extends Lager
HolzLager extends Lager

IRohstoffe (interface)
Stein implements IRohstoffe
Holz implements IRohstoffe


die Add methode könnte für SteinLager da zb so aussehen
Java:
public boolean add(Stein rohstoffe){
    if(cur_ress+ rohstoffe.getValue() < max_stein){
           cur_ress+= rohstoffe.getValue();
           System.out.println("Rohstoff kann eingelagert werden");
           return true;
    }
    return false;
}

cur_ress kannst du in die abstrakte Klasse hoch ziehen.
Wenn du nun sowas wie Lager leeren hinzuügen willst, dann kann man das in die abstrakte klasse machen, da dies für alle Lager gleich ist.

in der main Könnte es dann so hier aussehen:

Stein stein = new Stein();
SteinLager lager = new SteinLager();
lager.add(stein);

Die Methode mit der Vererbung ist zwar mehr als mit Generics aber es wird auf jedenfall übersichtlicher.

Und noch ein Tip zum Code Style. Entweder Englisch oder Deutsch für Variablen Klassen usw.

Ich hoffe ich hab dein Problem richtig erkannt und kann dir damit weiter helfen.
 

Leo123

Mitglied
Vielen Dank!
Dein Beispiel zum Programmaufbau hat mir sehr geholfen und werde ich nach meiner nächsten
Prüfung auf jedenfall ausprobieren. Mir ist schon häufiger aufgefallen, dass ich beim Programmieren immer deutsche und englische Begriffe verwende. Muss ich auf jedenfall dran arbeiten und mich entscheiden ;-)

Generics sind soo frustrierend ;(
Jedes mal, wenn man denkt, man hätte es endlich zu 10 % verstanden... kommt wieder ein Dämpfer :D
Kennt ihr empfehlenswerte Bücher/Ebooks über Generics? (Möglichst mit Anwendungsbeispielen(vielleicht sogar im "Spiele"-Bereich?))

Galileo Java und "Fortgeschrittene Programmierung mit java 5" haben wir zwar geholfen,
aber irgendwie bin ich noch zu Blöd für :D

An sich das Verständnis geht einigermaßen.. aber irgendwie kommts mir so vor, als ob
man alles ohne Generics (und viel einfacher) lösen kann. (obwohl es ziemlich warscheinlich Blödsinn ist) :)
 

anti-held

Bekanntes Mitglied
Mit Generics könntest du arbeiten, falls du für jeden Typen verschiedene Lager anlegen willst!

Mit [c]Lager<Stein> steinlager = new Lager<Stein>();[/c] würdest du ein neues Lager für Steine anlegen.
Deine add Methode würde dann z.B. nur Steine akzeptieren!

Somit würden deine instanceof Aufrufe nicht mehr benötigt.
Du könntest deine verschiedenen memberVariablen durch 2 allgemeine ersetzten, da ja jedes Lager blos einen Wert
beinhaltet.

z.B.

Java:
public class Lager<T extends Rohstoffe> {
	
	private int currentValue = 0;
	private int maxValue = 1000;

	public boolean add(T rohstoff) {
		if(!checkSize(rohstoff.getValue())){
			return false;
		}
		currentValue+=rohstoff.getValue();
		return true;
	}
	
	private boolean checkSize(int value){
		return currentValue + value <= maxValue;
	}
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S ISO 8601 -> getter / setter String Allgemeine Java-Themen 3
B Methoden Java Getter und Setter Methoden Allgemeine Java-Themen 9
F ArrayList`s in Klassen mit Getter/Setter Allgemeine Java-Themen 8
J unterschiedliche Objekte, selbe getter und setter Allgemeine Java-Themen 15
L Getter und Setter Verständnisfrage Allgemeine Java-Themen 10
M Einkapselung, Getter und Setter Allgemeine Java-Themen 6
D Design ohne Getter und Setter Allgemeine Java-Themen 8
G setter und getter: Parameter Überprüfung Allgemeine Java-Themen 6
wachtda Getter und Setter Allgemeine Java-Themen 1
J getter und setter Allgemeine Java-Themen 29
K java.lang.reflect - Getter und Setter ermitteln Allgemeine Java-Themen 8
S Noch eine Design-Frage zu Setter Allgemeine Java-Themen 6
N Eigenschaften eines Buttons per Setter verändern Allgemeine Java-Themen 5
perlenfischer1984 Java Builder vs Setter Allgemeine Java-Themen 1
S Klassen Prüfungen im Setter Allgemeine Java-Themen 6
J Setter mittels invoice aufrufen Allgemeine Java-Themen 4
V Setter zum Berechnen nutzen? Allgemeine Java-Themen 5
M Setter-Methode wird aufgerufen aber ändert nichts? Allgemeine Java-Themen 8
C setter funktionieren nicht Allgemeine Java-Themen 10
F Getter Methode aufrufen funktioniert nicht Allgemeine Java-Themen 1
I Java Optional: Nutzung als Getter? Angenommen? Allgemeine Java-Themen 11
X public Getter ersetzen (Reflection?!) Allgemeine Java-Themen 3
MQue getter- Methode, Generics Allgemeine Java-Themen 3
D Darf ich jakarta bibliotheken ohne weiteres nutzen? Allgemeine Java-Themen 10
G weiteres Java Programm vom Applet aus starten? Allgemeine Java-Themen 9

Ähnliche Java Themen

Neue Themen


Oben