# [Greenfoot] Zugriff auf Subclass von Actor in Subclass von World



## Domi741 (20. Dez 2011)

Hallo,

ich habe hier in der Klasse "Actor" eine Subklasse "Walk" sowie eine Subklasse "City" in der Klasse "World".

Nun möchte ich in der Subklasse "City" auf die Subklasse "Walk" zugreifen, genauer gesagt auf die Methoden "getXPos()" und "getYPos()".

Wie kann ich das realisieren?

Lg Dominic


----------



## Michael... (20. Dez 2011)

Domi741 hat gesagt.:


> Nun möchte ich in der Subklasse "City" auf die Subklasse "Walk" zugreifen, genauer gesagt auf die Methoden "getXPos()" und "getYPos()".


Ich nehme mal an es geht hier nicht um die Klassen sondern die daraus gebildeten Objekte:
Ganz allgemein muss das Objekt vom Typ City eine Referenz auf das Objekt vom Typ Walk besitzen. Diese Referenz könnte von einem anderen Objekt/ einer anderen Klasse die beide Objekte kennt übergeben werden.


----------



## Domi741 (20. Dez 2011)

Michael... hat gesagt.:


> Ich nehme mal an es geht hier nicht um die Klassen sondern die daraus gebildeten Objekte:


Ja sry, das meinte ich 



Michael... hat gesagt.:


> Ganz allgemein muss das Objekt vom Typ City eine Referenz auf das Objekt vom Typ Walk besitzen. Diese Referenz könnte von einem anderen Objekt/ einer anderen Klasse die beide Objekte kennt übergeben werden.


Das kriege ich ja eben nicht hin habe in der Klasse City oben wo ich die Variablen initialisiere folgendes hingeschrieben:

```
private Walk walkObject;
```

Wenn ich nun in der Methode, von der Klasse City, auf die "getXPos()" bzw. auf die "getYPos()" zugreifen möchte funktioniert das nicht. Habe es wie folgt versucht:


```
int x = walkObject.getXPos();
int y = walkObject.getYPos();
```

was ist daran falsch? =/


----------



## Michael... (20. Dez 2011)

Gibt es denn eine Klasse/Objekt die beide Objekte kennt?
Wenn City z.B. folgende Methode hätte:

```
public void setWalk(Walk walk) {
    walkObject = walk;
}
```
Könnte diese Klasse die Referenz auf das Walk Objekt übergeben.


----------



## Domi741 (20. Dez 2011)

Verstehe nicht wie du das meinst, Michael. =/

Vielleicht sollte ich dazu sagen, dass ich mich damit noch nicht solange auseinander setze. Allerdings aufgrund von PHP-Kenntnissen und ein wenig C#, doch einigermaßen vorankomme.

Hier mal ein Ausschnitt auf der Klasse City:

```
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class City extends World
{
    private Walk walkObject;
   
    /**
     * Erzeugt 'anzahl' an Frauen und fügt sie an zufälligen Positionen in der Welt ein.
     */
    private void addFrauen(int anzahl) {
        for(int i=1;i<=anzahl;i++) {
            int x = walkObject.getXPos();
            int y = walkObject.getYPos();
            
            addObject(new Frau(), x, y);
        }
    }
}
```

Und hier ein Ausschnitt aus der Klasse "Walk":

```
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Walk extends Actor
{
    /**
     * Generiert eine X-Koordinate
     */
    public int getXPos()
    {
        World myWorld = getWorld();
        int x = Greenfoot.getRandomNumber(myWorld.getWidth());
    
        if(x < 21) {
            x = 21;
        }
        if(x >= myWorld.getWidth()-21) {
            x = myWorld.getWidth()-21;
        }
        
        return x;
    }
    
    /**
     * Generiert eine Y-Koordinate
     */
    public int getYPos()
    {
        World myWorld = getWorld();
        int y = Greenfoot.getRandomNumber(myWorld.getHeight());        
       
        if(y < 21) {
            y = 21;
        }
        if(y >= myWorld.getHeight()-21) {
            y = myWorld.getHeight()-21;
        }
        
        return y;
    }
}
```

Die Methode "getWorld()" gibt eine Referenz auf das World-Objekt zurück.

Vielleicht hilft das ein wenig?!


Lg


----------



## Michael... (20. Dez 2011)

Kenne greenwood und die Zusammenhänge nicht.
Wo wird denn eine City Objekt und ein Walk Objekt erzeugt? Eventuell kann man das Walk Objekt in City neu erzeugen.


----------



## Domi741 (20. Dez 2011)

Also bei Greenfoot gibt es Klassen die vordefiniert sind, u.a. World und Actor.

Von diesen Klassen werden Subklassen abgeleitet mit welchen dann Interagiert wird (ich hoffe so kann man das sagen).

Die Klasse City ist bei mir eine Subklasse von World, die Klasse Walk ist eine Subklasse von Actor.

Vielleicht hilft es dir wenn du hier einmal kurz überfliegst was World und Actor genau ist. Kann das leider net so gut erklären =/

Aber trotzdem Danke für deine Mühe =)

Lg


----------



## guest0815 (20. Dez 2011)

Wie du selbst schreibst, sind das vordefinierte *Klassen*. Von Instanzenbildung ist in deinem Quelltext aber noch nichts zu sehen.


----------



## Domi741 (20. Dez 2011)

guest0815 hat gesagt.:


> Wie du selbst schreibst, sind das vordefinierte *Klassen*. Von Instanzenbildung ist in deinem Quelltext aber noch nichts zu sehen.



Das ist ja das Problem, wenn ich oben schreibe:


```
private Walk walkObject = new Walk();
```

dann macht er das nicht, deswegen habe ich mich ja hier ans Forum gewandt.

Lg


----------



## guest0815 (20. Dez 2011)

Wie bitte?

Diese Quellcode-Zeile hast du bis jetzt noch mit keinem Wort erwähnt. Oben stand klipp und klar nur 

```
private Walk walkObject;
```
Und das ist schlicht und ergreifend nur die Deklaration einer Referenz und keine Instanziierung.

Und was soll an 

```
private Walk walkObject = new Walk();
```
nun nicht funktionieren?

Wenn du Hilfe erwartest solltest du schon mal konkrete Fehlermeldungen rüberbringen.


----------



## Domi741 (20. Dez 2011)

du kommst ehrlich gesagt ziemlich unfreundlich rüber... aber OK. 
Ja ich weiß, ich benötige Hilfe, aber trotzdem kann man da ja trotzdem eine gewisse freundlichkeit an den Tag bringen...


habe oben das "= new Walk()" weggelassen wegen der Fehlermeldung!

nun habe ich es wieder eingefügt nun sieht das ganze wie folgt aus:


```
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class City extends World
{
    private Walk walkObject = new Walk();

    /**
     * Erzeugt 'anzahl' an Frauen und fügt sie an zufälligen Positionen in der Welt ein.
     */
    private void addFrauen(int anzahl) {
        for(int i=1;i<=anzahl;i++) {
            int x = walkObject.getXPos();
            int y = walkObject.getYPos();
                        
            addObject(new Frau(), x, y);
        }
    }
}
```

Als Fehlermeldung erhalte ich dann folgendes:

```
java.lang.NullPointerException
	at City.addFrauen(City.java:39)
	at City.<init>(City.java:27)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at greenfoot.core.Simulation.newInstance(Simulation.java:520)
	at greenfoot.platforms.ide.WorldHandlerDelegateIDE$3.run(WorldHandlerDelegateIDE.java:406)
	at greenfoot.core.Simulation.runQueuedTasks(Simulation.java:411)
	at greenfoot.core.Simulation.maybePause(Simulation.java:269)
	at greenfoot.core.Simulation.runContent(Simulation.java:201)
	at greenfoot.core.Simulation.run(Simulation.java:194)
java.lang.NullPointerException
	at Walk.getYPos(Walk.java:66)
	at City.addFrauen(City.java:40)
	at City.<init>(City.java:27)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at greenfoot.core.Simulation.newInstance(Simulation.java:520)
	at greenfoot.platforms.ide.WorldHandlerDelegateIDE$3.run(WorldHandlerDelegateIDE.java:406)
	at greenfoot.core.Simulation.runQueuedTasks(Simulation.java:411)
	at greenfoot.core.Simulation.maybePause(Simulation.java:269)
	at greenfoot.core.Simulation.runContent(Simulation.java:201)
	at greenfoot.core.Simulation.run(Simulation.java:194)
```

Lg


----------



## Michael... (20. Dez 2011)

Der Sinn der Klasse Walk ist mir nicht ganz klar.
Logisch wäre für mich wenn Frau von Actor erbt und City mehrere Frau Objekt erzeugt per setLocation deren Position gesetzt wird. Was da Walk zu tun hat - da es ja scheinbar nur zum generieren zufälliger Positionen genutzt wird - habe ich nicht verstanden.


----------



## Domi741 (20. Dez 2011)

Michael... hat gesagt.:


> Der Sinn der Klasse Walk ist mir nicht ganz klar.
> Logisch wäre für mich wenn Frau von Actor erbt und City mehrere Frau Objekt erzeugt per setLocation deren Position gesetzt wird. Was da Walk zu tun hat - da es ja scheinbar nur zum generieren zufälliger Positionen genutzt wird - habe ich nicht verstanden.



In Walk sind noch weitere Methoden definiert, unter anderem wie sich die Frau und noch weitere Elemente auf der Welt bewegen. Die Elemente (Frau, Mann, u.a.) werden alle als Subklassen von der Walk Klasse abgeleitet. Nur weil sie an sich mit meinem Problem nix zu tun haben, habe ich das hier weggelassen. =)


----------



## guest0815 (20. Dez 2011)

Domi741 hat gesagt.:


> du kommst ehrlich gesagt ziemlich unfreundlich rüber... aber OK.
> Ja ich weiß, ich benötige Hilfe, aber trotzdem kann man da ja trotzdem eine gewisse freundlichkeit an den Tag bringen...


Ich bin nicht unfreundlich, sondern höchstens direkt. 


> habe oben das "= new Walk()" weggelassen wegen der Fehlermeldung!


Und scheinbar hast du noch diverses anderes einfach weggelassen.
Allein schon aus den Zeilennummern der Fehlermeldung und der Tatsache, dass World nur diese Konstruktoren hat World (Greenfoot API) 
folgt, dass da wohl noch einiges fehlt. Sonst wäre das überhaupt nicht kompilierbar.

Also noch mal: Wenn du Hilfe willst, dann poste die *gesamte Klasse*!


----------



## Domi741 (20. Dez 2011)

```
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * City: Basisklasse für das Erzeugen der Welt.
 * 
 * @author möp
 * @version 2012-12-20
 */
public class City extends World
{
    private Walk walkObject = new Walk();
    
    /**
     * Constructor for objects of class City.
     */
    public City()
    {    
        
        // Create a new world with 700x600 cells with a cell size of 1x1 pixels.
        super(700, 600, 1); 
        setBackground("hintergrund.jpg");
        
        addXYZ(1);
        addZXY(10);
        addXZY(2);
        
        addFrauen(4);
        addMaenner(4);
        
        
    }
    
   
    /**
     * Erzeugt 'anzahl' an Frauen und fügt sie an zufälligen Positionen in der Welt ein.
     */
    private void addFrauen(int anzahl) {
        for(int i=1;i<=anzahl;i++) {
            int x = walkObject.getXPos();
            int y = walkObject.getYPos();
                        
            addObject(new Frau(), x, y);
        }
    }

     /**
     * Erzeugt 'anzahl' an Männern und fügt sie an zufälligen Positionen in der Welt ein.
     */
    private void addMaenner(int anzahl) {
        for(int i=1;i<=anzahl;i++) {
            int x = Greenfoot.getRandomNumber(getWidth());
            int y = Greenfoot.getRandomNumber(getHeight());
            
            if(x < 21) {
                x = 21;
            }
            if(x >= getWidth()-21) {
                x = getWidth()-21;
            }
            if(y < 21) {
                y = 21;
            }
            if(y >= getHeight()-21) {
                y = getHeight()-21;
            }
            
            addObject(new Mann(), x, y);
        }
    }


    [....]
}
```

an der Stelle "[....]" habe ich die Methoden "addXYZ()", "addZXY()" und "addXZY()".

Im Prinzip sind die 3 nur Kopien, von addMaenner, nur das ein anderes Objekt in die Welt gesetzt wird. und das hat nix mit dem Problem an sich zu tun. ich möchte halt einfach die x und y Koordinate mit meinen 2 Methoden die ich bereits in einer anderen Klasse deklariert habe bestimmen. Die beiden Methoden sind in der Walk Klasse deklariert, weil in Unterklassen auch auf die beiden Methoden zugreife und mir einfach das neu deklarieren ersparen wollte.


// EDIT

ich glaube ich hab den Fehler gefunden, die Methoden getYPos und getXPos, greifen mit der methode getWorld auf eine Referenz der World zurück. Könnte es sein dass sich die beiden da blockieren? und dadurch die fehler entstehen?

Werde glaub ich einfach die Methoden getXPos und getYPos nochmal in City deklarieren dann sollte das problem behoben sein, dann könnte ich ja vllt umgekehrt auf die Methoden zugreifen.


----------



## Michael... (20. Dez 2011)

Muss City nicht im Konstruktor erst das walkObjekt per addObjekt "in sich aufnehmen"? Sonst fehlt dem walkObjekt der World Kontext - wenn ich das richtig deute.


----------



## Domi741 (21. Dez 2011)

@Michael: siehe Edit vom Vorpost 

und dann noch aktueller Stand:

Habe nun einfach in beiden Klassen die Methoden deklariert und es funktioniert. es spart trotzdem noch einige zeilen Code ein 

Aber trotzdem danke für die Hilfe. =)


----------

