# Externer Methodenaufruf, Punkt-Notation



## Ionc (3. Dez 2011)

Hallo zusammen,

erst mal zu mir:
Ich habe seit ein paar Wochen den Informatik- Kurs für Objektorientierte Programmierung mit Java in der Schule belegt, und bin grad dabei mir die Grundlagen zuzulegen. Wir benutzen BlueJ, aber das dürfte ja zumindestens vom Namen her bekannt sein.

So, das Projekt lautet jetzt zwei "Flughäfen" zu Programieren.
Das klingt erstmal ziemlich banal, doch ich habe ein konkretes Problem.

Wenn beim ersetn Flughafen ein Flugzeug abhebt, soll an dem anderen landen, was sich im Status der Landebahn wiederspiegelt( Frei/ Besezt).
Führe ich also am ersten Flughafen die Methode starten aus, soll am ersten Flughafen die Landebahn frei(true), und am anderen besezt(false) werden.

Bisher hatte ich an soetwas gedacht, da ich keine static Methoden verwenden soll(haben wir noch nicht im Kurs gemacht), und ich ja ein Objekt brauche um aus der anderen Klasse drauf zugreifen zukönnen.

Klasse 1
[Java]public class Flughafen_nord
{
    boolean bahnfrei_nord;

    public Flughafen_nord()
    {
        Flughafen_nord fhn = new Flughafen_nord();
    }

      public void starten_nord()
    {
        bahnfrei_nord = true;
    }
}

[/Java]


Klasse 2:



```
public class Flughafen_sued
{
    public boolean bahnfrei_sued;
    
    public Flughafen_sued()
    {
        bahnfrei_sued = true;
    }
    
    public  void landen_sued()
    {
        bahnfrei_sued = false;
    }
}
```

Allerdings bekomme ich jetzt wenn ich ein Objekt von der Klasse Flughafen_nord erstellen will die Fehlermeldung :


```
java.lang.StackOverflowError
	at flughafen_sued.<init>(flughafen_sued.java:6)
	at flughafen_sued.<init>(flughafen_sued.java:7)
```

Denke ich zu kompliziert? :bahnhof:
Versteht maan überhaupt was ich meine? 
Danke für Hilfe soweit schon mal


MFG

Ionc


----------



## irgendjemand (3. Dez 2011)

aua ... das war wohl nichts


```
public Flughafen_nord()
    {
        Flughafen_nord fhn = new Flughafen_nord();
    }
```
ist eine endlose rekursion ... und somit nicht möglich

jedes mal wenn du von FlughafenNord *den underscore nutzt man in java nur bei konstanten* erzeugst du INNERHALB dieses konstruktors ein neues , völlig sinnloses objekt *da du es ja nirgendspeicherst* ...

alleinde wenn du dir den satz durch liest stellst du fest : und willst ein Objekt erstellen welches bei seiner erstellung ein neues Objekt des selben typs erstellen will ...

selbst wenn du irgend n abbruchbedingung hättest gehört rekursion NICHT in einen konstruktor *zumindest fällt mir keine sinnvolle verwendung dafür ein*

da mir auch nicht einleuchten will warum du überhaupt innerhalb eines konstruktors ein objekt von dem typ erzeugen willst was du gerade erzeugst ... würde ich dir sagen dich doch noch mal mit Objekten und Konstruktoren auseinander zu setzen

*google -> javainsel konstruktor*


----------



## faetzminator (3. Dez 2011)

Ja natürlich.

```
public Flughafen_nord() {
    Flughafen_nord fhn = new Flughafen_nord();
}
```
Du erstellst im Konstruktor ein neues Objekt, welches dann wieder dessen Konstruktor aufruft, welches ein neues Objekt erstellt, welches ...
Abgesehen davon schreibt man Klassen Camel Case mit beginnendem Grossbuchstabe, also [c]FooBarBazQuoz[/c] und nicht [c]Foo_bar_baz_quoz[/c].
Und ich glaub, du könntest einfach mit einer Klasse [c]Flughafen[/c] arbeiten, welche einen allgemeineren boolean verwalten ([c]istBahnFrei[/c]?).


----------



## Ionc (3. Dez 2011)

irgendjemand hat gesagt.:


> aua ... das war wohl nichts
> 
> 
> ```
> ...



Ja das stimmt. Und doch weis ich immer noch nicht wie ich jetzt weiter vorgehen soll.
Modularisierung soll nämlich vorkommen. Muss [c]     Flughafen_nord fhn = new Flughafen_nord(); [/c]
in eine eigene Methode?


----------



## faetzminator (4. Dez 2011)

Du musst diese Zeile dorthin schreiben, wo du ein Objekt dessen benötigst... Wo das nun ist kann ich ohne Glaskugel leider nicht herausfinden, ist gerade in Reparatur  Was der allgemeine Einstiegspunkt eines Javaprogrammes ist, solltest du allerdings wissen.


----------



## Ionc (4. Dez 2011)

Whoo das war wohl gestern ein bisschen spät 
Also ich hab jetzt meinen Quelltext ein bisschen verändert und hoffe ich kann jetzt mein Problem zum Ausdruck brigen:

Klasse 1(sued)


```
public class FlughafenSued
{
    public boolean bahnfreiSued;
    
    public FlughafenSued()
    {
        bahnfreiSued = true;
    }
    
    public  void landenSued()
    {
        bahnfreiSued = false;
    }
}
```

Klasse 2(nord)


```
public class FlughafenNord
{
    boolean bahnfreiNord;
   
      public void startenNord()
    {
        bahnfreiNord = true;
        FlughafenSued.landenSued();
    }
}
```

Ich möchte also mit der Methode [c] public void startenNord()[/c] , in der Klasse [c] public class FlughafenNord[/c] die Methode [c] public  void landenSued()[/c] in der Klasse [c]public class FlughafenSued [/c] ausführen.

Doch jetzt gibt mir der Compiler den Fehler 
[c] non static method cannot referenced from a static context [/c]
zurück. Gibt es eine Möglichkeit dies ohne eine statische Methode zu lösen? Ich muss wahrscheinlich ja ein Objekt mit dem new-Operator erzeugen. Doch an welcher Stelle????:L

Danke nochmal für Hilfe

Ionc


----------



## faetzminator (4. Dez 2011)

Öhm dort wo du das Objekt benötigst. Ich weiss irgendwie immer noch nicht so ganz, was du machen Willst. Müssen beide "Flughäfen" aufeinander referenzieren? Dann mach zwei Setter-Methoden.

```
Flughafen a = new Flughafen();
Flughafen b = new Flughafen();
a.setXY(b);
b.setXY(a);
```


----------



## gman (4. Dez 2011)

```
FlughafenSued.landenSued();
```

Das ist ein statischer Zugriff auf die Methode "landenSued()". Du brauchst das was 
faetzminator geschreiben hat und dann:


```
public class FlughafenNord
{
    boolean bahnfreiNord;
    FlughafenSued flughafenSued;
   
      public void startenNord()
    {
        bahnfreiNord = true;
        flughafenSued.landenSued();
    }

    public void setFlughafenSued(FlughafenSued flughafenSued) {
        this.flughafenSued = flughafenSued;
    }
}
```

Allerdings könnte man das auch allgemeiner modellieren. Z.B. eine Flughafen-Klasse und
in der Main-Methode nur zwei Objekte der Klasse anlegen (Nord und Sued halt).


----------



## Ionc (4. Dez 2011)

Vielen Dank schonmal, doch leider bekomme ich jetzt, wenn ich die [c] public void startenNord()[/c] Methode ausführen will den Fehler [c]java.lang.NullPointerException
	at FlughafenNord.startenNord(FlughafenNord.java:14)
[/c]

Andersherum, mit Sued natürlich das gleiche.

Mein Quelltext sieht jetzt so aus :
[Java]
public class FlughafenNord
{
    boolean bahnfreiNord;
    FlughafenSued flughafenSued;

    public FlughafenNord()
    {
        bahnfreiNord = false;
    }

      public void startenNord()
    {
        bahnfreiNord = true;
        flughafenSued.landenSued();
    }

    public void setFlughafenSued(FlughafenSued flughafenSued) {
        this.flughafenSued = flughafenSued;
    }

    public void landenNord()
     {
         bahnfreiNord = false;
     }
}
[/Java]


Wäre es auch möglich mir kurz zu erklären wofür 

```
public void setFlughafenSued(FlughafenSued flughafenSued) {
        this.flughafenSued = flughafenSued;
    }
```
und Zeile 4 verwendet wird, und was es eigentlich ist 

Danke


----------



## Michael... (4. Dez 2011)

Ionc hat gesagt.:


> Wäre es auch möglich mir kurz zu erklären wofür
> 
> ```
> public void setFlughafenSued(FlughafenSued flughafenSued) {
> ...


die ist dafür da um die NullPointerException zu vermeiden ;-)
Ernsthaft: Wenn ein Objekt A eine Methode an einen Objekt B aufrufen will, muss A Objekt B kennen bzw. auf dieses zugreifen können. Diese Methode ist dafür gedacht ein Objekt vom Typ FlughafenSued, dem Objekt vom Typ FlughafenNord bekannt zu machen. Damit Nord später auch dessen landen... Methode aufrufen kann.

Von den Vorschlägen nur eine Flughafen Klasse zu schreiben und für beide Flughäfen zu nutzen hälst Du wohl nichts ;-)


----------



## Dragonfire (4. Dez 2011)

Sind diese beiden Klassen vorgegeben?
Ich würde das ein wenig anders lösen ...

Ein Flughafen ist ein Objekt,
Ein Objekt hat gewisse Eigenschaften ...

Ein Flughafen hat in deinem Beispiel einen Namen, als String (Süd, Nord)
und eine Belegung ob die Flugbahn frei ist (boolean).

Dies setzen wir mal flott um:


```
public class Airport {

    private String name;
    private boolean empty;

    public Airport (String airportName) {
        name = airportName;
        empty = true;
    }

    public void landOnAirport() {
        empty = false;
    }

    public void flyAway() {
        empty = true;
    }
}
```

Unser Flughafen kann jetzt aber noch nicht viel, vor allem gibt es irgendwie keine Verbindung zum anderen Flughafen (es existieren keine Beziehungen).

Bei deinem Beispiel hat jeder Flughafen einen Nachbarflughafen,
also machen wir das auch mal schnell plus das Herz,
ein Flugzeug kann zu einem anderen Flughafen fliegen:



```
public class Airport {

    private String name;
    private boolean empty;
    private Flughaben neighbour;

    public Airport (String airportName) {
        name = airportName;
        empty = true;
    }
    
    public void landOnAirport() {
        empty = false;
    }

    public void flyAway() {
        empty = true;
    }

    public void flyToNeighbour() {
        flyAway();
        neighbour.landOnAirport();
    }
    
    public void setNeighbour(Airport neighbourAirport) {
        neighbour = neighbourAirport;
    }
}
```

Jetzt spielen wir Flughafentower ...
Ich weiß nicht mehr wie genau,
aber ich meine du konntest in BlueJ Objekte erstellen und Methoden aufrufen:

Erstell einmal 

```
a1 = new Airport("Süd")
```
und

```
a2 = new Airport("Nord")
```

dann setze die Nachbarflughäfen:


```
a1.setNeighbour(a2)
```
und 

```
a2.setNeighbour(a1)
```

Jetzt 
solltest du flyToNeighbour aufrufen können.
Mach eventuell noch ein paar Testausgaben rein, um zu sehen was passiert 
Das Programm überprüft nicht ob man landen kann, dass kannst du ja selbst realisieren^^

ALLES UNGETESTET ...

PS.: Willst du keine festen Nachbarn setzen kann man es auch so machen:


```
public class Airport {

    private String name;
    private boolean empty;

    public Airport (String airportName) {
        name = airportName;
        empty = true;
    }
    
    public void landOnAirport() {
        System.out.println("Airplane land on " + this.name);
        empty = false;
    }
    
    public void flyAway() {
        System.out.println("Airplane fly away from " + this.name);
        empty = true;
    }
    
    public void flyToAirport(Airport target) {
        flyAway();
        target.landOnAirport();
    }
}
```


----------



## Ionc (4. Dez 2011)

Vielen vielen Dank Dragon Fire!

Ich habe mich jetzt auch für diese Lösung entschieden, da es so wohl am einfachsten ist.
Ich sollte in meiner aufgabe nur Modularisierung verwenden, doch diese werde ich jetzt an anderer Stelle einsetzten.
Hab deine Lösung jetzt ersteinmal noch ein bisschen abgewandelt, doch jetzt weis ich wie ich weiter machen kann.
Habe jetzt auch keine festen "nachbarn" benutzt.

Danke, ich makier das Thema als erledigt.


MFG

Ionc( eigentlich IonIc;p)


----------

