Warum wird bei Java die Variable "doppelt" eingeführt?

...komplette Frage anzeigen

4 Antworten

dogsAge gibt es nur innerhalb von Dog().
age = dogsAge bewirkt, dass das Alter im Objekt gespeichert wird und später darauf zugegriffen werden kann.

Was mich allerdings irritiert ist, dass age nicht bereits bei Animal deklariert wurde, denn jedes Tier hat ein Alter.

Danke! Ich glaube ich habe es verstanden!
Das Beispiel ist ein bisschen unglücklich denn die Klasse Animal existiert zu dem Zeitpunkt an dem ich das Beispiel rauskopiert habe noch nicht :D Man fängt mit der dog Klasse an und fügt dann die Animalklasse hinzu und schafft die Attribute die nicht Hundespezifisch sind dann erst rüber :D

2
@Docenock

Achso, gut, das wusste ich nicht. Im Rahmen dieser Lehrbeispiele ist ja fast alles erlaubt.

3

Ich würde, wenn ich auf Variablen des Objekts zugreife, grundsätzlich immer das Schlüsselwort "this" verwenden. Dann können lokale Variablen und Objektvariablen auch den gleichen Namen haben. Über "this" wird dann jeweils die Objektvariable angesprochen. Ansonsten "verdecken" lokale Variablen die Objektvariablen (shadowing).

Außerdem würde ich die Variable als "private" deklarieren. Außerdem könnte man sie hier, da sie nur im Konstruktor gesetzt wird und ansonsten nie wieder schreibend auf sie zugegriffen wird, sogar als "final" deklarieren.

class Dog extends Animal {
private final int age;

public Dog(int age) {
this.age = age;
}

public int getAge() {
return this.age;
}

}

Sobald Du Code hast, der das Alter verändert (das Alter verändert sich ja schon dadurch, dass Zeit verstreicht), musst Du das "final" entfernen.

Das Schlüsselwort "this" gibt Dir eine Referenz auf das aktuelle Objekt (auf das die Methode aufgerufen wurde). Lokale Variablen gleichen Namens "verdecken" Objektvariablen (shadowing).

Ich empfinde das "this" auch so (wenn kein shadowing stattfindet), als "guten Stil", sozusagen um noch einmal explizit hinzuschreiben, dass ich hier auf eine Objektvariable zugreife.

Wenn es nach mir ginge, könnte die Sprache den Zugriff auf Objektvariablen und Methoden ohne das Schlüsselwort "this" (oder allgemein eine Objektreferenz) verbieten. Leider ist dem aber nicht so. Ich programmiere trotzdem so, als wäre dem so. Empfinde ich als "guten Stil". Man muss nicht alles machen, was die Sprache einem erlaubt. Wenn man eine bestimmte Sache "expliziter" tun kann, als von der Sprache gefordert, ist es oft auch gut, dies zu tun, weil man damit aktiv dokumentiert, dass man wirklich genau dies möchte (z. B. eben auf das Objekt zugreifen).

Die Antwort ist in der Summe sehr ausführlich, mit ein paar mehr Details noch die ich nicht erwähnte. 

das mit dem Shadowing sehe ich prinzipiell ja schon ein. und age hier doppelt zu verwenden ebenso. Allerdings this an allen möglichen Stellen zu verwenden leuchtet mir jedoch nicht so ganz ein. - Bei Instanz-Variablen finde ich es bei der Leserlichkeit zwar auch besser, jedoch stünde diese Option dann auch noch für Methoden zu Verfügung - und da würde ich bei Methodenaufrufen eher auf ein this verzichten.

1
@KnusperPudding

Das stimmt. Bei Methoden gibt es im Prinzip keine Doppeldeutigkeit, daher wäre das "this" redundant. Aber es dient der Konsistenz. Wenn Du auf einem "fremden" Objekt eine Methode aufrufst, schreibst Du "objektreferenz.methode(...)". Für den Spezialfall, dass Du die Methode "auf Dir selbst" aufrufst, ist die Objektreferenz eben das Schlüsselwort "this".

Es bringt aber nichts, sich darüber zu streiten, deswegen werde ich das an dieser Stelle auch nicht tun. ;-)

Syntaktisch ist beides korrekt, das heißt dem Rechner ist es "egal". Es ist gewissermaßen persönliche Präferenz. Dereferenzieren muss die JVM bei Methodenaufrufen ohnehin, das heißt das "this." bewirkt keine zusätzliche Dereferenzierungsoperation, die Laufzeit kostet (auch wenn es zunächst so aussehen mag).

1
@NoHumanBeing

Mir ginge es nicht ums 'Streiten', nur manchmal verstehe ich andere 'Ansichten' nicht, bin aber froh wenn ich noch dazu lernen kann.

1
@KnusperPudding

Hatte es auch nicht als "Streit" interpretiert. Ich wollte nur sagen, ich werde jetzt nicht in eine Diskussion ausarten, ob man es so oder so machen sollte, denn es wird sehr wahrscheinlich darauf hinauslaufen, dass wir beide es weiterhin so machen werden, wie wir es bisher für richtig hielten und das ist ja auch in Ordnung so. ;-)

1

Bei dieser Zeile:

public Dog(int dogsAge) {

Handelt es sich um den Konstruktor, mit dem eine Instanz einer Klasse gebildet wird. - Dieser Instanz gibst du eine Zahl mit: dogsAge. - mit dem Aufruf des Konstruktors wird durch den Parameter dogsAge die Instanz-Variable: age befüllt.

Die Variable dogsAge hätte nur Gültigkeit innerhalb des Konstruktors, dadurch dass die Instanz-Variable age gesetzt wurde, kann dieser von überall innerhalb der Instanz verwendet werden.

In wie weit das 'Sinn' macht, hängt davon ab, wie dein restlicher Code aussieht. und in wie weit du die Variable noch weiter verwendest.

Hey Danke schonmal!
Später greift das Programm nochmal auf die Variable zu auf diese Weise:

public int getAge() {
return age;

Wenn ich dich richtig verstanden habe könnte er garnicht auf dogsAge zugreifen, daher muss man age=dogsAge setzen, oder?
Vielen Dank :)

2

Genau das ist der Punkt den du lernen sollst über objektorientiere Programmierung. Da finde ich C# besser, da man da Eigenschaften einer Klasse direkt speichern und ansprechen kann.

Bei Java werden klasseninterne Eigenschaften als 'private' deklariert und dann über getter- und setter-Funktionen angesprochen.

Die set-Funktion musst du dir Vorstellen wie ein Befehl, den du an den Hund gibst. Du sagst dem Hund also "du bist jetzt soviele jahre alt". Das "soviele" entspricht also deinem "dogsAge". Mit dieser Information setzt der Hund intern sein Alter.

Warum macht man das so und nicht anders? Nun...es gibt Situationen, da muss man etwas mehr machen als nur das Setzen. Oder es wird intern noch in Tage umgerechnet und nach aussen immer in Jahre. oder oder oder. Auf Klasseninterne Variablen sollte man direkt niemals zugreifen dürfen (rechte). Daher das bitte immer über getter- und setter-Funktionen kapseln

Ich hoffe ich konnte dir helfen

Gruß
Omni

Was möchtest Du wissen?