Java / Greenfoot: Wie bekomme ich es hin, dass die Klasse von Objekt 1 auf die Variablen von der Klasse von Objekt 2 zugreifen kann?

2 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Hallo 123montag123,

nun Du hast doch beide Objekte mit "new" instanziert, oder?
Das musst Du einer Variablen zuweisen, damit erhälst Du eine Referenz auf das Objekt.

MyClass myObject = new MyClass();

myObject enthält nun eine Referenz auf das Objekt vom Typ MyClass.

Wenn Du nun von einem anderen Objekt darauf zugreifen willst, dann musst Du nur diese Referenz weitergeben und dann kannst Du die öffentlichen Methoden benutzen.

Beispiel:

MyClass myObject = new MyClass();
MyOtherClass myOtherObject = new MyOtherClass();
myOtherObject.setPartner(myObject);

setPartner könnte so aussehen:

public void setPartner(MyClass partner) {
   this.partner = partner; //damit es auch wirklich ein setter ist :D
   int x = partner.get(x);
   //....
}

Du musst letzendlich die Referenz auf ein Objekt weitergeben, damit ein anderes Objekt diese nutzen kann.

Gruß

Woher ich das weiß:Berufserfahrung

123montag123 
Beitragsersteller
 04.09.2019, 19:16

Was meinst du mit Referenz?

0
123montag123 
Beitragsersteller
 04.09.2019, 19:55

Kannst du mir die setpartner methode erklären? Wofür steht das this? Ich bin noch absoluter Anfänger.

0
AldoradoXYZ  04.09.2019, 20:14
@123montag123

Ganz umgangssprachlich ausgedrückt (die ganze Theorie dahinter ist noch etwas komplizierter und sicherlich auch mal lesenswert, aber für den Anfang nicht wirklich wichtig):

Also eine Referenz ist nicht das Objekt selbst, sondern nur ein "Hinweis" darauf, wo das Objekt im Speicher ist.

MyClass myObject = new MyClass();

"myObject" ist damit eine Referenz auf das Objekt, welches mit "new MyClass()" erzeugt wurde.

Wozu braucht man Referenzen? Warum schreibt man nicht:

new MyClass();

So erzeugst Du auch ein Objekt, aber Du kannst nicht mehr darauf zugreifen. Das Objekt wird im Speicher angelegt, aber Du hast keine Referenz auf das Objekt um auf das Objekt zuzugreifen.

Mit einer Referenz auf ein Objekt kannst Du nun auf das Objekt zugreifen. Und Du kannst diese Referenzen auch an andere Objekte weitergeben, damit diese auf das Objekt zugreifen können.

Dazu gibst Du einfach die Variable/die Referenz per Paramter an ein Objekt weiter und genau das macht meine Set-Methode.

public void setPartner(MyClass partner) {
   this.partner = partner; //damit es auch wirklich ein setter ist :D
   int x = partner.get(x);
   //....
}

Die Methode heißt setPartner. Und "partner" ist der einzige Paramter. Vor dem Parameter "partner" steht der Typ, den dieser Parameter haben muss, nämlich "MyClass". Das heißt Du kannst die Methode mit einem String, oder einem Integer aufrufen, oder irgend welchen anderen Typen (Klassen), Du kannst nur Referenzen vom Typ MyClass übergeben.

Zum Thema "this". This bezieht sich auf das aktuelle Objekt "in dem man sich befindet". Die setPartner Methode ist Teil der Klasse MyOtherClass, damit bezieht sich "this" auf das Objekt dieser Klasse. Jetzt fragst Du vielleicht "warum kann man this nicht weglassen"?

public void setPartner(MyClass partner) {
   partner = partner;
...

Das Problem hier ist, dass sich "patner = " auf den Paramter bezieht. Ich würde also den Parameter partner mit sich selbst überschreiben. Wenn ich this nicht benutzen will, dann könnte ich auch einfach einen anderen Namen wählen:

public void setPartner(MyClass partner) {
   partnerOfThisClass = partner;

Hier wähle ich einen anderen Namen. Sieht man auch häufiger. Aber ich möchte mir keine Namen ausdenken müssen, nur weil ich this nicht verstanden habe.

Natürlich ist klar, dass ich dann ein Member in der Klasse haben muss, was so aussehen muss:

private MyClass partnerOfThisClass;

oder im ersten Fall

private MyClass partner;

Mir hat am Anfang das hier geholfen:

Klassen sind Baubeschreibungen für Objekte. Objekte sind dann konkrete Ausprägungen.

Du kannst zum Beispiel eine Klasse Auto haben. Diese Klasse hat viele Attribute wie zum Beispiel die Farbe. Nun erzeugt man ein Objekt der Klasse Auto und dieses Objekt bekommt eine ganz konkrete Farbe.

So gibt es eine Klasse Auto, aber viele AutoObjekte. Jedes AutoObjekt kann seine eigene Farbe haben. Im Bauplan (der Klasse) steht nur, dass ein Auto eine Farbe haben muss, aber nicht welche konkret.

"this" bezieht sich demnach auf das konkrete Auto-Objekt. Man könnte es auch mit "ich" übersetzen. "this.color" wäre dann die Farbe des Auto-Objekts und bezieht sich auf das Attribut:

private Color color;

Wenn Du verstanden hast, was eine Referenz ist, dann ist this einfach nur die Selbstreferenz.

Am Anfang ist Objektorientierung sehr ungewohnt und seltsam. Aber mit etwas Erfahrung ist es ganz natürlich. Wir haben Baupläne und wir Bauen Objekte danach, das machen wir auch in der physischen Welt genau so.

Und kleiner disclaimer: Ja, das ist alles sehr umgangssprachlich formuliert, aber man muss irgendwo anfangen. Wenn jemand so weit ist, dann kommt er auch dazu sich mit Polymorphie und co. zu beschäftigen. Aber will man einen Anfänger damit wirklich belästigen, wenn es genau 0 bringt?

Gruß

1
123montag123 
Beitragsersteller
 05.09.2019, 09:13
@AldoradoXYZ

Können Sie mir sagen, was genau in welcher Klasse steht und vielleicht noch ein Beispiel machen?

0
AldoradoXYZ  05.09.2019, 16:07
@123montag123

Also this.partner = partner sorgt dafür, dass die Referenz gespeichert wird. Aber mal ein einfaches Beispiel was mehr nach deinem ersten Beispiel aussieht:

public class Car {
    private int x;
    private int y;

    public Car(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void printSame(Car otherCar) {
        int otherX = otherCar.getX();
        int otherY = otherCar.getY();

        if (this.x == otherX && this.y == otherY) {
            System.out.println("ja");
        } else {
            System.out.println("nein");
        }
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }
}

Und dazu eine Main:

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        Car carOne = new Car(12, 41);
        Car carTwo = new Car(12, 41);

        carOne.printSame(carTwo);
    }
}

Im Konstruktor der Main-Klasse werden zunächst zwei Cars erzeugt. carOne und carTwo. Dann wird die printSame-Methode von carOne aufgerufen, als Parameter wird carTwo übergeben (eine Referenz auf das Objekt carTwo).

So, wie funktioniert nun die Car-Klasse, der Bauplan für Cars?

Car hat zwei Member-Variablen x und y, die beide vom Typ int sind. So hat ein Car immer eine Position, die aus x und y besteht.

Der Konstruktor "public Car(int x, int y)..." ist nun dafür zuständig Objekte dieser Klasse Car zu erzeugen. Damit verspricht der Konstruktor, dass er Car-Objekte erstellen kann. Der Konstruktor hat einfach nur zwei Parameter x und y beide vom Typ int. Diese beiden Parameter werden auch einfach nur an x und y des Objekts zugewiesen. Dies geschieht mit

this.x = x;

Warum nicht einfach

x = x;

Weil sich dann das x links vom Gleichheitszeichen auf den Parameter beziehen würde und nicht auf x der Member-Variable. Beide haben den selben Namen. Wird etwas mit einem Namen gesucht, dann wird immer von innen nach außen gesucht, von unten nach oben.

Da kannst Du selbst mal ausprobieren wie das funktioniert:

System.out.println(x);
int x = 5;

funktioniert nicht.

Aber:

int x = 5;
System.out.println(x);

funktioniert. Reihenfolge ist wichtig. Wird das x nicht oberhalb der Nutzung in der Methode gefunden, so wird überprüft ob es eine Member-Variable mit dem Namen x gibt. Gibt es die auch nicht, dann kommt es zum Fehler. Gibt es eine Member-Variable, dann wird auf diese zugegriffen.

Wenn ich aber gar nicht erst in der Methode nach der Variable suchen will, dann benutze ich gleich this um direkt die Member-Variable zu nutzen.

In der Methode:

public int getX() {
    return this.x;
}

benutze ich gleich this.x. Hätte ich nicht machen müssen. Das Verhalten wäre ohne this ganz genauso. Zunächst würde in der Methode oberhalb das x gesucht, gibt es nicht. Auch gibt es keinen Parameter der so heißt. Zuletzt würde dann eine Membervariable x gefunden. Und die Membervariable kann man auch direkt mit this.x ansprechen.

Zur printSame Methode:

public void printSame(Car otherCar) {
    int otherX = otherCar.getX();
    int otherY = otherCar.getY();

    if (this.x == otherX && this.y == otherY) {
        System.out.println("ja");
    } else {
        System.out.println("nein");
    }
}

Diese Methode hat einen Parameter. Sie erwartet eine Referenz auf ein Car-Objekt. Die Methoden (getX(), getY()) des Car-Objekts werden dann auch benutzt um die x und y Werte zu holen. Diese Werte werden dann mit dem aktuellen Objekt geschrieben.

Wieder habe ich this.x geschrieben. Hätte ich das machen müssen? Würde es auch einfach so gehen?

if (x == otherX && y == otherY) {
        System.out.println("ja");
} 

Probier es einfach mal aus und überlege warum es geht, oder nicht geht.

Gruß

0