# Java Klassen mit ID



## numpad (23. Sep 2012)

Hey,
ich bin im moment dabei, ein kleines Spiel für Java zu programmieren (nur zum üben) und habe den anfang jetzt schon fertig, stehe aber jetzt vor einem Problem: Ich habe eine Klasse (Pressure), welche eine Druckplatte darstellen soll.
So sieht meine Klasse aus:

```
import java.awt.Point;
import java.awt.Rectangle;

public class Pressure {

	private static String id;
	private static int x,y,width,height;
	
	public Pressure(int x, int y, int width, int height, String id){
		Pressure.x = x;
		Pressure.y = y;
		Pressure.width = width;
		Pressure.height = height;
		Pressure.id = id;
	}
	
	public static String pressedPlate(){
		Point pt1 = new Point(Player.x + (Player.width /2), Player.y + Player.height);
		
		if (new Rectangle(x,y,width,height).contains(pt1)){
			return id;
		} else {
			return "none";
		}
	}
}
```

Nur will ich jetzt, dass ein Text über die Console ausgegeben wird, je nach dem, was für eine ID die Platte hat.
So rufe ich die Klasse auf:

```
//wird immer ausgeführt, wenn ich space drücke
public static void allTheCollisions(){
		if (pres.pressedPlate() == "hat"){
			System.out.println("hat");
		} else if (pres.pressedPlate() == "skin"){
			System.out.println("skin");
		}
		else {
			System.out.println("none");
		}
	}
```
Und so definiere ich sie:

```
public static Pressure pres;

public Game(Frame f){ //hauptklasse
		[...]
		new Pressure(200,110,75,40, "skin");
		new Pressure(160,110,75,40, "hat");
                [...]
```

Das Problem:
Jetzt wird nur etwas ausgegeben, wenn ich auf der Pressure mit der ID "hat" stehe, sonst wird nur "none" ausgegeben.

Wie kann ich dass machen, ohne dass ich jede einzelnde Pressure definieren muss, also so:

```
public static Pressure pres1, pres2, pres3; //usw...


pres1 = new Pressure(x,y,width,height);
pres2 = new Pressure(x2,y2,width2,height2);
pres3 = new Pressure(x3,y3,width3,height3);
```


----------



## bwbg (23. Sep 2012)

Ich habe Deinen Post jetzt nur flüchtig gelesen, aber sind die ganzen statischen Attribute/Methoden wirklich das, was Du willst?

Grüße


----------



## Final_Striker (23. Sep 2012)

Die Attribute in deiner Klasse sind static, deshalb sind die in allen deinen Pressure-Objekten identisch.

Strings sind Objekte und Objekte vergleicht man mit equals und nicht mit ==


```
pres1 = new Pressure(x,y,width,height);
pres2 = new Pressure(x2,y2,width2,height2);
pres3 = new Pressure(x3,y3,width3,height3);
```

Welche Id sollten diese Objekte deiner Meinung nach denn bekommen?


----------



## numpad (23. Sep 2012)

Final_Striker hat gesagt.:


> Die Attribute in deiner Klasse sind static, deshalb sind die in allen deinen Pressure-Objekten identisch.


Heißt dass, ich muss nur das "static" davor wegmachen, und es klappt?



Final_Striker hat gesagt.:


> Strings sind Objekte und Objekte vergleicht man mit equals und nicht mit ==


Ok danke 
Ich bin neu in Java^^



Final_Striker hat gesagt.:


> ```
> pres1 = new Pressure(x,y,width,height);
> pres2 = new Pressure(x2,y2,width2,height2);
> pres3 = new Pressure(x3,y3,width3,height3);
> ...



Habe das "hat" bzw "skin" usw. vergessen.
Sollte eigentlich so aussehen:


```
pres1 = new Pressure(x,y,width,height, "hat");
pres2 = new Pressure(x2,y2,width2,height2, "skin");
pres3 = new Pressure(x3,y3,width3,height3, "hat");
```


----------



## freez (24. Sep 2012)

numpad hat gesagt.:


> ```
> public class Pressure {
> private static String id;
> private static int x,y,width,height;
> ```



Dein Problem sind diese "statics" ... [c]Pressure.id[/c] gibt es in deiner ganzen Anwendung nur ein einziges mal. Sobald du deine zweite Instanz erstellst, ist die ID trotzdem die vom ersten und über deinen Konstruktor überschreibst du die ID und es bleibt nur die ID von der letzten erstellten Instanz bestehen. Also, [c]static[/c] wegnehmen und schon sollte es so gehen, wie du es brauchst.

Ich empfehle dir diese kurze Lektüre zum besseren Verständnis.


----------



## freez (24. Sep 2012)

Noch ein kleines Beispiel zum besseren Verständnis:

```
public class StaticTest {
	int x;
	static int y;
	public StaticTest(int x, int y) {
		this.x = x;
		StaticTest.y = y;
	}

	@Override
	public String toString(){
		return "x: " + x + " / y: " + y;
	}
	public static void main(String[] args) {
		StaticTest [] arr = new StaticTest[10];
		for(int i = 0; i < arr.length; i++)
			arr[i] = new StaticTest(i, i);

		for(StaticTest item : arr)
			System.out.println(item);
	}
}
```

Hier kannst du gut erkennen, was mit der static Variable [c]y[/c] passiert. Obwohl ich immer die Laufvariable [c]i[/c] der FOR Schleife einspeichere, bleibt der letzte Konstruktoraufruf in [c]y[/c] gespeichert.


----------



## numpad (24. Sep 2012)

freez hat gesagt.:


> Dein Problem sind diese "statics" ... [c]Pressure.id[/c] gibt es in deiner ganzen Anwendung nur ein einziges mal. Sobald du deine zweite Instanz erstellst, ist die ID trotzdem die vom ersten und über deinen Konstruktor überschreibst du die ID und es bleibt nur die ID von der letzten erstellten Instanz bestehen. Also, [c]static[/c] wegnehmen und schon sollte es so gehen, wie du es brauchst.
> 
> Ich empfehle dir diese kurze Lektüre zum besseren Verständnis.



Jetzt habe ich das "static" vor dem "public [STRIKE]static[/STRIKE] String id;" weggenommen, aber eclipse zeigt mir jetzt an:


----------



## bone2 (24. Sep 2012)

da fehlen ja elementare grundlagen
Galileo Computing :: Java ist auch eine Insel - 3 Klassen und Objekte

die methode darf auch nicht mehr static sein


----------



## ARadauer (24. Sep 2012)

numpad hat gesagt.:


> Heißt dass, ich muss nur das "static" davor wegmachen, und es klappt?


nö du musst static verstehen sonst macht das alles keinen sinn ;-)


----------



## Empire Phoenix (24. Sep 2012)

kurz alle platten in ne arraylist packen, arraylist ist statisch.

dann mit ner for schleife alle platten testen ob wer draufsteht, und wenn ja platte returnen, sonst null returnen.


----------



## numpad (24. Sep 2012)

ARadauer hat gesagt.:


> nö du musst static verstehen sonst macht das alles keinen sinn ;-)


Ich habe mal ein Tutorial über Java geguckt, und da hieß es, dass static nur heißen, dass die Methode auch von anderen Klassen aufgerufen werden kann.



bone2 hat gesagt.:


> da fehlen ja elementare grundlagen
> Galileo Computing :: Java ist auch eine Insel - 3 Klassen und Objekte
> 
> die methode darf auch nicht mehr static sein



Wenn ich das static davor wegmache, sieht es in meiner Main-class so aus:


----------



## freez (25. Sep 2012)

numpad hat gesagt.:


> Ich habe mal ein Tutorial über Java geguckt, und da hieß es, dass static nur heißen, dass die Methode auch von anderen Klassen aufgerufen werden kann.



Das ist falsch. Dafür sorgt [c]public[/c] (oder auch [c]protected[/c] aber nur begrenzt). [c]static[/c] lässt dich Methoden aufrufen, ohne eine Instanz deiner Klasse zu benötigen. Hat natürlich den Nachteil, dass die statischen Werte nur einmal pro Klasse existieren, aber die nicht statischen Werte pro Instanz existieren. Hat mit der Sichtbarkeit der Methode nix zu tun. 

Wenn du objektorientiert Programmieren möchtest (und scheinbar wolltest du es ja mit deinem Programm erreichen), solltest du [c]static[/c] vermeiden.



numpad hat gesagt.:


> Wenn ich das static davor wegmache, sieht es in meiner Main-class so aus:


Ganz ehrlich: Du solltest dich doch noch etwas tiefer mit Tutorials oder besser noch einen Buch beschäfftigen (z.B. kostenlos URL). Du brauchst von deiner Klasse eine Instanz über die du dann auf die Methoden zugreifen kannst. Das sind Basics in der Java Programmierung, die du können solltest.


```
Presure p = new Pressure();
if("hate".equals(p.pressedPlate()))
   doSomeThing();
```


----------



## ARadauer (25. Sep 2012)

ARadauer hat gesagt.:


> nö du musst static verstehen sonst macht das alles keinen sinn ;-)



ich hab das ernst gemeint... http://www.java-forum.org/stichwort...ic-method-cant-referenced-static-context.html
das musst du verstehen...


----------



## numpad (25. Sep 2012)

ARadauer hat gesagt.:


> ich hab das ernst gemeint... http://www.java-forum.org/stichwort...ic-method-cant-referenced-static-context.html
> das musst du verstehen...



Ja, ich weiß, dass du das ernst gemeint hast.
Ich hatte nur gehofft, das mir hier jem. eine Antwort geben kann, damit ich es verstehen kann. Ich will und werde es natürlich nicht einfach abschreiben.


Ausserdem was ich nicht verstanden habe:


```
public class Pressure {

	public [STRIKE]static[/STRIKE] String id;
	private static int x,y,width,height;
	
	public Pressure(int x, int y, int width, int height, String id){
		Pressure.x = x;
		Pressure.y = y;
		Pressure.width = width;
		Pressure.height = height;
		this.id = id;
	}
	
	public static String pressedPlate(){
		Point pt1 = new Point(Player.x + (Player.width /2), Player.y + Player.height);

		if (new Rectangle(x,y,width,height).contains(pt1)){
			return [U][B][COLOR="Red"]id[/COLOR][/B][/U];
		} else {
			return "none";
		}
	}

}
```

Wenn ich da dass static vor dem "String id" wegmache, kann ich ja nicht mehr darauf zugreifen. Wie kann ich das lösen?

Edit:
Bezüglich zu dem Link, den du mir gesendet hast, dass ist genau dass, was ich *nicht* will.
In dem Link nennt "Beni" ein beispiel, was mir nicht weiterhilft, da ich dass auch schon kann.

Beispiel von "Beni":

```
public class Test{
    public static void main( String[] args ){
        Test heinz = new Test( "Heinz" );
        Test werner = new Test( "Werner" );
 
        heinz.doSomething();
        werner.doSomething();
    }
 
    private String name;
    public Test( String name ){
        // Das ist gar keine Methode, das ist ein Konstruktor :-)
        this.name = name;
    }
    public void doSomething(){
        // Das ist eine nicht-statische Methode
        System.out.println( "Hallo :-), ich bin " + name );
    }
}
```


```
Test heinz = new Test( "Heinz" );
Test werner = new Test( "Werner" );
```
Genau das "Test heinz = " und dass "Test werner = " will ich weglassen können. So könnte ich das natürlich auch, aber ich will die möglichkeit haben, das einfach zu machen, ohne das "Test heinz = ", also nur "new Test("Heinz")".


----------



## ARadauer (25. Sep 2012)

weil das static bei presedPlate natürlich falsch ist.

this.id = id; ich finds schade, dass das überhaupt compiliert...

Pressure mhn druck... ist auch irgendwie ein unguter name...

ok mal was anderes
Mensch -> Klasse 
Max Musterman -> Objekt

static bezieht sich auf die Klasse
pressedPlate sowas wie ähmn schreibeName, wie kann das satic sind? Was weiß die Menschheit schon von Max Musterman ;-)

Player.width ? ist das auch static? schlecht...

Ich weiß auch woher das kommt.. da gibt einen Haufen youtube spiele programmier tutorials von leuten die keine Ahnung von Objektorietierung haben... da kann man zwar schnell coole sachen machen, abe sauber ists nicht...


----------



## numpad (25. Sep 2012)

ARadauer hat gesagt.:


> weil das static bei presedPlate natürlich falsch ist.
> 
> this.id = id; ich finds schade, dass das überhaupt compiliert...
> 
> ...



Ich habe mir ein paar Videos von "Ulixava" auf YouTube angesehen.


----------



## numpad (25. Sep 2012)

Einmal das ganze Spiel zum verständnis:






Die orangen Pfeile zeigen überall dahin, wo eine Druckplatte bzw Pressure erstellt werden soll.
Die gelben Felder sind überall, wo ich eine Pressure erstellt habe, der rote Text darin die *id* (new Pressure(x,y,width,height,"hat" / "skin")).

der grüne Punkt ist der erkennbereich.

Wenn ich jetzt die Taste "SPACE" drücke, wird überprüft, ob der Spieler auf einer, und wenn ja auf welcher, Druckplatte / Pressure der Spieler steht (erkennbereich). Wenn er auf einer Pressure mit der id "hat" steht, soll "hat" in der Console ausgegeben werden, wenn er auf der mit der id "skin" steht, soll "skin" ausgegeben werden.


Natürlich könnte ich es wie folgt definieren:

```
pres1 = new Pressure(x,y,width,height, "hat");
pres2 = new Pressure(x2,y2,width2,height2, "skin");
pres3 = new Pressure(x3,y3,width3,height3, "hat");
```

Aber ich möchte nur dass "new Pressure([...]);" schreiben, also ohne "pres1 = ".
Das klappt soweit auch, nur leider nur bei der letzten Pressure, die ich definiert habe, dh:

```
new Pressure(0,0,100,100,"hat");
new Pressure(100,100,200,200, "skin");
```
Hier wird nur etwas ausgegeben, wenn ich auf der Pressure "skin" stehe, wenn ich auf der mit der id "hat" stehe, erscheint standartgemäß nur "none", was immer erscheint, wenn ich auf keiner Pressure stehe.

Würde ich es sorum definieren:

```
new Pressure(100,100,200,200, "skin");
new Pressure(0,0,100,100,"hat");
```
Würde nur etwas ausgegeben, sofern ich auf der Pressure mit der id "hat" stehe.


----------



## X5-599 (25. Sep 2012)

Die Ploblematik ist nach wie vor: Wenn du statische Klassenattribute hast, die du auch noch beim Objekterzeugen immer neu setzt, ist immer nur das zuletzt gesetzte vorhanden. Das kommt daher daß diese Attribute "an der Klasse" hängen. Nicht an jedem einzelnen Objekt (das bekämst du hin, wenn du das static überall weglässt).

Wie möchtest du denn überhaupt diese Preasure Objekte benutzen? Wie werden sie erzeugt/ausgewertet?


----------



## numpad (25. Sep 2012)

X5-599 hat gesagt.:


> Die Ploblematik ist nach wie vor: Wenn du statische Klassenattribute hast, die du auch noch beim Objekterzeugen immer neu setzt, ist immer nur das zuletzt gesetzte vorhanden. Das kommt daher daß diese Attribute "an der Klasse" hängen. Nicht an jedem einzelnen Objekt (das bekämst du hin, wenn du das static überall weglässt).
> 
> Wie möchtest du denn überhaupt diese Preasure Objekte benutzen? Wie werden sie erzeugt/ausgewertet?



Ich will sie so benutzen:
Ich gehe mit meinem Charakter rum und dann drücke ich irgendwann mal die Space Taste. Wenn ich diese drücke, wird überprüft ob ich in einer Pressure (new Pressure(x,y,width,height,id) stehe, also ob mein character in der x,y,width und height koordinate ist.
Wenn er in der mit der id "hat" ist, soll ein bestimmter Text ausgegeben werden, wenn er auf einer, mit der id "skin" ist, ein anderer, vorbestimmter text.


----------



## X5-599 (26. Sep 2012)

Das hört sich wirklich danach an, dass diese Preasure Objekte komplett eigenständig sein können. Static Notwendigkeit sehe ich hier nicht. Wenn du die Preasure Objekte nicht irgendwo halten möchtest (z.b. in einer ArrayList) könntest du einfach:


```
if(new Pressure(10,20,100,50,"hat").pressedPlate().equals("wasAuchImmer"))
{
}
```

schreiben. Somit wird halt jedesmal beim Abfragen ein neues Preasure Objekt erstellt, welches aber nach der Abfrage nicht mehr existiert (zugreifbar ist).


----------



## freez (26. Sep 2012)

Dein Problem liegt doch schon in der Definition:

[c]Pressure[/c] ist eine Klasse, in der definiert ist, welche Eigenschaften ein Objekt vom Typ Pressure hat (x, y, width, height, id). Im Objekt selbst sind dann die Eigenschaften mit Werten befüllt (x=10, y=20....). Also brauchst du mehrere Objekte ([c]new Pressure(...)[/c]), da du mehrere Druckplatten mit unterschiedlichen Werten hast. Durch diese Definition ist hier einfach kein Platz für [c]static[/c].

[c]static[/c] darfst du gern da benutzen, wo du ausschliesslich nur ein Objekt benötigst, da alle dieselben Informationen enthalten (z.B. eine Konfiguration für dein Programm). In dem Fall sind redundante Informationen überflüssig. 

Du hast doch aber keine redundanten Informationen in deinen Druckplatten, oder?


[EDIT]Dann gleich noch einen Tipp: nehme deine 5 Druckplatten und speichere sie in einer Liste. Dann brauchst du sie nur durchzugehen, wenn du SPACE drückst und den Treffer zurückgeben. Dann wäre es sogar egal, wie viele Druckplatten du hast.[/EDIT]


----------



## numpad (26. Sep 2012)

X5-599 hat gesagt.:


> Das hört sich wirklich danach an, dass diese Preasure Objekte komplett eigenständig sein können. Static Notwendigkeit sehe ich hier nicht. Wenn du die Preasure Objekte nicht irgendwo halten möchtest (z.b. in einer ArrayList) könntest du einfach:
> 
> 
> ```
> ...



Danke klappt jetzt (fast) genauso wie ich es wollte.


----------

