# Guter Stil von Beginn an (this oder expliziete Parameter)



## Mik3e (8. Juni 2005)

Hi!

Vorweg: Ich arbeite mich gerade in Java ein. Nachdem ich aber schon seit sehr langer Zeit mit anderen (strukturierten) Programmiersprachen arbeite, weiß ich, dass es meist wichtig ist, einen guten Stil zu entwickeln. Und das wenn möglich von Beginn an (hat man einmal einen "schlampigen" Stil, kommt man da nur schwer raus)   

Daher zu meiner Frage an erfahrene Leute:
Wenn ich Methoden für ein bestimmtes Objekt aufrufe, kann ich das Objekt ja explizit als Parameter definieren oder einfach in der Methode mit "this" zugreifen.

*Variante A (Explizit):*

```
public class TestProgramm {
     public static void main (String[] args) {
          Fahrzeug meinauto=new Fahrzeug();
          meinauto.setGewicht(meinauto,852);
     }
}

class Fahrzeug {
     private int gewicht=0;
     public void setGewicht(Fahrzeug fz, int gewicht) {
          fz.gewicht=gewicht;
     }
}
```

*Variante B (Implizit / mit this):*

```
public class TestProgramm {
     public static void main (String[] args) {
          Fahrzeug meinauto=new Fahrzeug();
          meinauto.setGewicht(852);
     }
}

class Fahrzeug {
     private int gewicht=0;
     public void setGewicht(int gewicht) {
          this.gewicht=gewicht;
     }
}
```
Welche der beiden Methoden ist besser? Ich könnte mir vorstellen, dass das Variante A bei einer komplexen Struktur der bessere Stil wäre (da mehr beschreiben). In diversen Tutorials habe ich sowohl die eine als auch die andere Variante gesehen.

Vielleicht könnt Ihr mir aus Erfahrung sagen, welche Variante die "besser" ist und ich von Beginn an durchziehen sollte. Möglicherweise ist es ja auch absolut egal und wirklich reine Geschmackssache (was ich nicht glaube).

Danke vorweg für Eure Tipps,
LG
Mike


----------



## zerix (8. Juni 2005)

Manchmal muss man this benutzen. z.b. bei übergabeparametern im Konstruktor 

MFG


----------



## Mik3e (8. Juni 2005)

Ja, aber was ist prinzipiell gebräuchlicher (wenn ich jetzt von dem simplen Beispiel ohne Konstruktor, Vererbungen oder ähnliches ausgehe)?


----------



## Romsl (8. Juni 2005)

Ich hab bis jetzt nur Variante B gesehen und denke auch, dass diese verwendet wird. Du hast ja die Referenz auf das erzeugte Fahrzeug schon und kannst mit setGewicht(35) auch auf dieses zugreifen und innerhalb dieser Methode dieses Gewicht setzen (mit this). Warum sollte es Sinn machen dieses Fahrzeug Objekt nochmal zu übergeben? this und fz referenzieren ein und das selbe Objekt.

Hoffe das stimmt auch was ich verzapft habe.

Gruß

Romsl


----------



## zerix (8. Juni 2005)

Noch Ergänzung zu meinem Post:

Mit dem this greifst du auf die globale Variable zu und ohne auf die der Methode. Wenn du 2 Variablen hast die den gleichen Namen haben musst du das so machen.

MFG


----------



## Mik3e (8. Juni 2005)

Das es technisch (vermutlich) belanglos ist, glaube ich auch (außer vielleicht performancemäßig). Ich wüßte halt gern, ob die "lange" (explizite) schreibweise vorteile bei der übersichtlichkeit bringt, wenn es Klassen gibt, die massig mit Methoden bestückt sind. Denn durch die Übergabe des Objekts beschreibt man die Methode ja noch etwas genauer...


----------



## Mik3e (8. Juni 2005)

Zu Zerix:
Das ist aber nur dann der Fall, wenn ich in der Methode noch eine Lokale Variable initialisiere, die (dummerweise) den selben namen wie die übergebene Instanz hat, oder?

Sorry, wenn ich hier vielleicht schwachsinn schreibe, aber wie gesagt arbeite ich mich gerade erst ein...


----------



## zerix (8. Juni 2005)

Du kannst das this bei jeder globalen Variable davor schreiben, aber du musst es nur tun, wenn sie wirklich den gleichen namen haben.


----------



## Thomas Darimont (8. Juni 2005)

Hallo!



> Das ist aber nur dann der Fall, wenn ich in der Methode noch eine Lokale Variable initialisiere, die (dummerweise) den selben namen wie die übergebene Instanz hat, oder?


Wenn man deine Aussage etwas umformuliert... ( wenn ich in dieser Methode eine Instanzvariable initialisiere die den selben Namen hat wie der dazugehörige Methodenparameter...)

... Ja. ob dass nur "Dummerweise" so ist hast du gesagt. Ich denke das dies Code ingesamt lesbarer macht...

Gruß Tom


----------



## zerix (8. Juni 2005)

Was meinst du mit "Denn durch die Übergabe des Objekts beschreibt man die Methode ja noch etwas genauer..."?


----------



## zerix (8. Juni 2005)

@ Tom

Das ist wohl war, vor allem bei großen Programmen mit SEHR vielen Variablen


----------



## Mik3e (8. Juni 2005)

Uff.. heiße Diskussion.. Komm ja mim Lesen nicht mehr nach   

Mit genauer Beschreiben meine ich, dass ich in der Methode bei den Parametern auch gleich sehe, für welchen Typ diese Methode gedacht ist.

Angenommen ich habe mehrere Klassen:
Auto, Motorrad, Flugzeug

Und jede besitzt die Methode "getGeschwindigkeit" sowie jeweils 50 andere.
Wenn ich nun den Sourcecode (mit 700 Zeilen   ) ansehe und bei einer Methode getGeschwindigkeit() lande, sehe ich auf den ersten Blick, für welchen Typ die Funktion gedacht ist.

(Ich gehe bei dem trivialen Beispiel davon aus, dass die Geschwindigkeit für jeden Typ anders berechnet wird)

Das meine ich mit "übersichtlicher"..


----------



## Thomas Darimont (8. Juni 2005)

Hallo!



> Du kannst das this bei jeder globalen Variable davor schreiben, aber du musst es nur tun, wenn sie wirklich den gleichen namen haben.


"Globale" Variablen gibt es unter Java nicht... es gibt statische Attribute die dann an eine Klasse und nicht an eine bestimmte Instanz gebunden sind. Dabei sollte man this. Weglassen und den entsprechenden Klassennamen vorransetzen... Was du meinst sind Instanzvariablen/Membervariablen/Instanzattribute etc.

Gruß Tom


----------



## Thomas Darimont (8. Juni 2005)

Hallo!



> Und jede besitzt die Methode "getGeschwindigkeit" sowie jeweils 50 andere.


Wenn jede Klasse diese Methode besitzt dann ist was faul an deinem Design.... -> Erzeuge eine entsprechende Basisklasse (leite die übrigen Klassen von dieser ab) und implementiere die "generischen" Methoden dort...

Gruß Tom


----------



## Mik3e (8. Juni 2005)

Da hast Du natürlich recht.. war ein schlechtes Beispiel. Sollte auch nur zur Veranschauung was ich mit "Beschreiben" meine dienen.

Also kann ich davon ausgehen, dass das "Angewöhnen" von "this" anstelle von expliziter Parametrisierung (außer in Fällen wo es sowieso benötigt wird) durchaus in Ordnung ist und nicht die Lesbarkeit des Quellcodes beeinträchtigt!?


----------



## Snape (8. Juni 2005)

Moin,
prinzipiell würde ich eher sagen, dass es schlechter Stil ist, einen Übergabeparameter so zu nennen wie eine Instanzvariable. Einfacher und weniger fehlerträchtig ist in diesem Fall deshalb z.B. die Verwendung von

public void setGewicht(int newGewicht)

an Stelle von

public void setGewicht(int gewicht)


----------



## zerix (8. Juni 2005)

@ Tom

Also ich hab das so gelernt das eine Variable die in der ganzen Klasse bekannt ist eine "Globale" Variable ist.
Und eine Variable die nur in ner Methode oder Anweisungsblock bekannt ist, eine "lokale" Variable ist.

Bei "Globalen" Variablen kann man dann this davor schreiben, muss man aber nicht, oder irre ich mich da


----------



## Mik3e (8. Juni 2005)

Das man nach Möglichkeit gut formulierte Variablenbezeichner nehmen sollte, ist klar (wie in jeder Programmiersprache ) (Der Variablenbezeichner "name" ist wahrscheinlich nicht sonderlich clever).

Andererseits habe ich bei Javabuch wieder gelesen, dass es nicht gut ist, Variablen oder Methoden mittels Bezeichner in Verbindung mit der zugehörigen Klasse zu bringen.

Schlecht:

Klasse Auto
   String autoname;
   boolean autokombi;
   methode autoBeschleunigen ()

Warum man das nicht so machen sollte, ist mir allerdings nicht wirklich klar...


----------



## Thomas Darimont (8. Juni 2005)

Hallo!



> Also ich hab das so gelernt das eine Variable die in der ganzen Klasse bekannt ist eine "Globale" Variable ist.


Kommt drauf an wie du "Globale Varaible definierst... für mich ist Instanzvariable != Globale Variable... eine Globale Variable entspricht für mich einer öffentlichen statischen Klassenvariable.



> Und eine Variable die nur in ner Methode oder Anweisungsblock bekannt ist, eine "lokale" Variable ist.


Das ist korrekt.



> Bei "Globalen" Variablen kann man dann this davor schreiben, muss man aber nicht, oder irre ich mich da


Wie gesagt nach deiner Definition sind für dich "Globale Variablen" Instanzvariablen ... ja davor kann man this schreiben um sie eindeutig zu identifizieren...

@Snape


> Moin,
> prinzipiell würde ich eher sagen, dass es schlechter Stil ist, einen Übergabeparameter so zu nennen wie eine Instanzvariable.


Jeder hat so seinen eigenen Stil... ich und meine Kollegen teilen die Meinung, dass es besserer Stil ist Konstruktorparameter so zu bennennen wie die entsprechenden Membervariablen und diese dann mit this bei der Zuweisung eindeutig zu qualifizieren...

Außerdem ist deine Argumentation etwas schwach...  welche Variante wäre denn hier "schicker" ?

```
/**
 * 
 */
package de.tutorials;

/**
 * @author Tom
 *
 */
public class BusinessObject {
	
	private boolean isNew;
	private Object someData;
....
	
	1)
	public BusinessObject(boolean isNewNew, Object someDataNew){
		isNew = isNewNew;
		someData = someDataNew;
	}
	
	2)
	public BusinessObject(boolean isNew, Object someData){
		this.isNew = isNew;
		this.someData = someData;
	}
....
}
```
1 oder 2? ;-)
Ich denke mit Variante 2) hat man eine konsequentere und eine einheitlichere Konvention.... und das ist wichtig bei großen Entwicklungsprojekten. Ich persönlich finde große Frameworks (wie etwa das Springframework) in denen dies konsequent Umgesetzt worden ist leichter zu erlernen und anzuwenden.

Gruß Tom


----------



## zerix (8. Juni 2005)

@ Tom

Ich hab das mal bei Google gesucht 

"Im Gegensatz zu lokalen Variablen stehen globale Variablen. Globale Variablen werden außerhalb der Funktionsdefinition deklariert. Sie haben außerhalb und innerhalb der Funktionsdefinition Gültigkeit."

Und so kenne ich das. Ist das falsch


----------



## hpvw (8. Juni 2005)

Also, die Variante A habe ich auch noch nie gesehen.
Die Variante B ist die, die ich kenne und verwende.


			
				zerix hat gesagt.:
			
		

> Bei "Globalen" Variablen kann man dann this davor schreiben, muss man aber nicht, oder irre ich mich da


Du musst this davor schreiben, wenn in der Methode (oder als Methodenparameter) eine Variable mit demselben Namen definiert ist. Kommt diese Variable nicht in der Methode vor, kannst Du this davor schreiben, musst es aber nicht.
Ich verwende auch in dem zweiten Fall immer this, da dann im Code auch bei längeren Methoden klar zu erkennen ist, auf was ich zugreife. Ob das jedoch in irgendeiner Codeconvention empfohlen oder als schlechter Stil angesehen wird, weiß ich nicht.
Bei Eclipse kann man sich das Fehlen von this als Warning oder Error einstellen. Das lässt vermuten, dass es verwendet werden sollte.

Bei Java sind es trotzdem Instanzvariablen 

Gruß hpvw


----------



## Thomas Darimont (8. Juni 2005)

Hallo!



> Sie haben außerhalb und innerhalb der Funktionsdefinition Gültigkeit.


... in Java spricht man nicht von Funktionen sondern von Methoden. Weiterhin ist diese Definition schwammig... wie gesagt ... was du meinst sind Instanz Variablen... diese sind innerhalb einer Instanz gültig... nicht jedoch unabhänig von einer konkreten Instanz. Im Gegensatz zu public static Attributen...

ich sag dazu nichts mehr.

Gruß Tom


----------



## zerix (8. Juni 2005)

Ok, danke!

Möchte mir ja nichts falsches einprägen 

mfg


----------



## Snape (8. Juni 2005)

Thomas Darimont hat gesagt.:
			
		

> Hallo!
> @Snape
> 
> Jeder hat so seinen eigenen Stil... ich und meine Kollegen teilen die Meinung, dass es besserer Stil ist Konstruktorparameter so zu bennennen wie die entsprechenden Membervariablen und diese dann mit this bei der Zuweisung eindeutig zu qualifizieren...



Über Geschmack lässt sich bekanntlich nicht streiten. 



> Außerdem ist deine Argumentation etwas schwach...  welche Variante wäre denn hier "schicker" ?
> 
> ```
> public class BusinessObject {
> ...



Du lernst ja auch durch Bücher alleine, das können auch nicht alle - mich eingeschlossen. 
Wie gesagt, Geschmacksache. isNewNew ist natürlich gaga...
Variante 1 sinnvoll geändert, und ich bin Dein Fan.


----------



## Mik3e (9. Juni 2005)

Danke für die konstruktiven Beiträge, werde mich für die kurze Variante "this" Variante entscheiden.

Noch 2 Fragen:

*@hpvw:*
Wo kann man das Warning in Eclipse einstellen? Wäre angenehm um das ganze zu vereinheitlichen und unterstützt mich sicher beim Lernen

*@alle:*
Noch eine Frage zu den Methoden:
Es darf ja syntaktisch mehrere Methoden mit dem selben Namen geben, da der Compiler anhand der Parameter unterscheidet. Bezieht sich diese Unterscheidung nur auf die Anzahl oder auch auf die Typen bzw. sogar auf die Variablendeklaration?

Ist zu deutsch folgendes erlaubt!?:


```
Methode 1: public void getStudentData (int x) {}
Methode 2: public void getStudentData (int y) {}
Methode 3: public void getStudentData (int x, int y) {}
Methode 3: public void getStudentData (Object a) {}
```

Oder würde der sich der Compiler hier irgendwo stoßen (vor allem bei 1 und 2)?

LG
Mike


----------



## Thomas Darimont (9. Juni 2005)

Hallo!



> Ist zu deutsch folgendes erlaubt!?:


Nicht komplett.... man nennt das ganze übrigens Methoden Überladung.

public abstract void getStudentData (int x);
public abstract void getStudentData (int y); <-- Nicht erlaubt, da schon eine Methode mit dem gleichen Namen und der selben Parametersignatur existiert...
public abstract void getStudentData (int x, int y);
public abstract void getStudentData (Object a);

Alle anderen Methoden sind gültig, da man sie durch Ihre Methodensignaturen eindeutig identifizieren kann, deine Namensgebung solltest du allerdings nochmal überarbeiten ;-).

Gruß Tom


----------



## zerix (9. Juni 2005)

Jepp, bei 1 und 2

Die Variable muss entweder von einem anderen Typ sein oder es müssen entweder mehr Variablen sein


----------



## Mik3e (9. Juni 2005)

Alles klar... 

@Tom:
Muss mich erst an die neuen Begriflichkeiten gewöhnen (Überladung, Überlagerung 
Wißt ihr vielleicht auch wegen den Eclipse Einstellungen (Warning bei this) Bescheid?


----------



## hpvw (9. Juni 2005)

Eclipse 3:
Window -> Preferences
Java -> Compiler -> Style
"Unqualified access to instance field" -> Warning

In der 2er war Warning glaube ich sogar Standard.


----------



## Mik3e (9. Juni 2005)

Danke.. arbeite mit 3.0.2... Ist also genau dort, wo Du beschrieben hast ;o))
Übrigens Danke an alle für die massigen Infos.. hat mich einiges weitergebracht


----------



## Romsl (9. Juni 2005)

Schließ mich voll und ganz der Meinung von Thomas an.

Wobei die Methode


```
public void getStudentData(...)
```

keinen Sinn (void) macht


----------



## Mik3e (9. Juni 2005)

Womit Du natürlich recht hast (void und get klingt unlogisch)... :suspekt:


----------

