Lernpfad:Objektorientierte Programmierung mit Java/Parameter und Rückgaben: Unterschied zwischen den Versionen

Aus Informatik-Box
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Zeile 2: Zeile 2:
{{Pfad|Methoden}} sind eine Reihe von Anweisungen, die mehrfach wiederverwendet werden können. Im Sinne der [[Strukturierte Zerlegung|strukturieren Zerlegung]] können so Teilprobleme gelöst werden und zur Lösung von komplexeren Problemen kombiniert werden.  
{{Pfad|Methoden}} sind eine Reihe von Anweisungen, die mehrfach wiederverwendet werden können. Im Sinne der [[Strukturierte Zerlegung|strukturieren Zerlegung]] können so Teilprobleme gelöst werden und zur Lösung von komplexeren Problemen kombiniert werden.  


In einem Zeichnprogramm könnte es zum Beispiel eine Methode <code>public void zeichneQuadrat()</code> geben. Sie würde immer das gleiche Quadrat zeichnen. Das wäre wenig sinnvoll, denn eigentlich sollen ja beliebige Quadrate gezeichnet werden können.  (Also mit beliebig großer Kantenlänge.)
In einem Zeichenprogramm könnte es etwa eine Methode <code>public void zeichneQuadrat()</code> geben. Sie würde immer das gleiche Quadrat zeichnen. Das wäre wenig sinnvoll, denn eigentlich sollen ja beliebige Quadrate gezeichnet werden können.  (Also mit beliebig großer Kantenlänge.)


== Parameter ==
== Parameter ==
Damit man nicht für alle möglichen Quadrate eigene Methoden schreiben muss (was ja gar nicht möglich ist, da es theoretisch unendlich viele Quadrate gibt), kann man der Methode mit einem '''Parameter''' sagen, wie groß das Quadrat werden soll.  
Damit man nicht für alle möglichen Quadrate eigene Methoden schreiben muss (was gar nicht möglich ist, da es theoretisch unendlich viele Quadrate gibt), kann man der Methode mit einem '''Parameter''' sagen, wie groß das Quadrat werden soll.  


<center><code>public void zeichneQuadrat( {{Farbig|double pKantenlaenge|orange}} )</code></center>
<center><code>public void zeichneQuadrat( {{Farbig|double pKantenlaenge|orange}} )</code></center>
Zeile 13: Zeile 13:
Die Paramtervariable ist dann im gesamten Methodenrumpf ''gültig'' und kann wie andere Variablen benutzt werden.  
Die Paramtervariable ist dann im gesamten Methodenrumpf ''gültig'' und kann wie andere Variablen benutzt werden.  


Eine Methode kann auch mehr als einen Parameter haben. Die Methode von oben könnte zu <code>zeichneRechteck</code> verallgemeinert werden und zwei Parameter für die beiden Kantenlangen bekommen:
Eine Methode kann auch mehr als einen Parameter haben. Die Methode von oben könnte zu <code>zeichneRechteck</code> verallgemeinert werden und zwei Parameter für die beiden Kantenlängen bekommen:


<center><code>public void zeichneRechteck( {{Farbig|double pKanteA, double pKanteB|orange}} )</code></center>
<center><code>public void zeichneRechteck( {{Farbig|double pKanteA, double pKanteB|orange}} )</code></center>


{{Kasten|Fur die Bezeichner von Parametern gelten dieselben Vorgaben wie für die von Variablen und Methoden. Um sie leichter von ''lokalen Variablen'' innerhalb des Methodenrumpfes unterscheiden zu können benutzt man häufig ein kleines "p" als Prefix. Dies ist aber nur eine Absprache unter Entwicklern, im den Quellcode besser lesbar zu machen. Man könnte als Bezeichner auch <code>xTezU</code> oder sonst einen Unsinn benutzen.|Farbe={{Farbe:Info}}}}
{{Kasten|Für die Bezeichner von Parametern gelten dieselben Vorgaben wie für die von Variablen und Methoden. Um sie leichter von ''lokalen Variablen'' innerhalb des Methodenrumpfes unterscheiden zu können, benutzt man häufig ein kleines "p" als Präfix. Dies ist aber nur eine Absprache unter Entwicklern, um den Quellcode besser lesbar zu machen. Man könnte als Bezeichner auch <code>xTezU</code> oder sonst einen Unsinn benutzen.|Farbe={{Farbe:Info}}}}


== Rückgabetypen ==
== Rückgabetypen ==
Zeile 47: Zeile 47:
</syntaxhighlight>
</syntaxhighlight>


Jede Anfrage '''muss''' mit einem <code>return</code> enden, das einen Wert des passenden Rückgabetyps zurückgibt. Das bedeutet auch, dass bei bedingten Anweisungen (if-Anweisungen) beide Alternativen am Ende zu einem <code>return</code> führen müssen.  
Jede Anfrage '''muss''' mit einem <code>return</code> enden, das einen Wert des passenden Rückgabetyps zurückgibt. Das bedeutet auch, dass bei bedingten Anweisungen (<code>if</code>-Anweisungen) beide Alternativen am Ende zu einem <code>return</code> führen müssen.  
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
public boolean istKleinerAlsVier( int pZahl ) {
public boolean istKleinerAlsVier( int pZahl ) {
Zeile 59: Zeile 59:


{{Rahmen|
{{Rahmen|
Die Methode aus dem letzten Beispiel kannst du auch ohne Bedingte Anweisung schreiben. Der Vergleich <code>pZahl < 4</code> ergibt einen Wahrheitswert (<code>boolean</code>). Ist dieser Wert <code>true</code>, dann wird <code>true</code> zurückgegeben. Ist er <code>false</code>, dann wird <code>false</code> zurückgegeben. Also könntest du auch direkt das Ergebnis des Vergleichs zurückgeben:
Die Methode aus dem letzten Beispiel kannst du auch ohne bedingte Anweisung schreiben. Der Vergleich <code>pZahl < 4</code> ergibt einen Wahrheitswert (<code>boolean</code>). Ist dieser Wert <code>true</code>, dann wird <code>true</code> zurückgegeben. Ist er <code>false</code>, dann wird <code>false</code> zurückgegeben. Also könntest du auch direkt das Ergebnis des Vergleichs zurückgeben:
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
public boolean istKleinerAlsVier( int pZahl ) {
public boolean istKleinerAlsVier( int pZahl ) {
Zeile 71: Zeile 71:


=== Call-by-value ===
=== Call-by-value ===
Handelt es sich um einen primitiven Datentyp, dann wird der Wert, mit dem die Methode aufgerufen wird als Kopie an die Methode übergeben. Änderungen an der Paramtervariablen wirken sich it innerhalb des Methodenrumpfes aus, nicht aber außerhalb der Methode.  
Handelt es sich um einen primitiven Datentyp, dann wird der Wert, mit dem die Methode aufgerufen wird als Kopie an die Methode übergeben. Änderungen an der Paramtervariablen wirken sich nur innerhalb des Methodenrumpfes aus, nicht aber außerhalb der Methode.  


Man spricht im deutschen von einem [[wikipedia:Wertparameter|Wertparameter]].
Man spricht im Deutschen von einem [[wikipedia:Wertparameter|Wertparameter]].


=== Call-by-reference ===
=== Call-by-reference ===
Handelt es sich im eine Objektreferenz, dann wird auch nur eine Referenz übergeben. Wie im Schritt {{Pfad|Referenzen}} beschrieben wird, handelt es sich dabei um einen Zeiger auf ein Objekt im Speicher. Änderungen an diesem Objekt wirken sich überall im Programm aus, nicht nur innerhalb der Methode.  
Handelt es sich um eine Objektreferenz, dann wird auch nur eine Referenz übergeben. Wie im Schritt {{Pfad|Referenzen}} beschrieben wird, handelt es sich dabei um einen Zeiger auf ein Objekt im Speicher. Änderungen an diesem Objekt wirken sich überall im Programm aus, nicht nur innerhalb der Methode.  


Man spricht im deutschen von einem [[wikipedia:Referenzparameter|Referenzparameter]].
Man spricht im Deutschen von einem [[wikipedia:Referenzparameter|Referenzparameter]].


=== Weiterführende Informationen ===
=== Weiterführende Informationen ===
{{Collapse:Start}}
{{Collapse:Start}}
In Java wird durch den Typ des Parameters die Aufrufart bestimmt. Primitive Typen werden immer als Wertparameter, Objekte als Referenzparamter übergeben. Um einen primitiven Typ als Referenz zu übergeben muss man seine {{Pfad|Generische Typen|Wrapperklasse}} benutzen.  
In Java wird durch den Typ des Parameters die Aufrufart bestimmt. Primitive Typen werden immer als Wertparameter, Objekte als Referenzparameter übergeben. Um einen primitiven Typ als Referenz zu übergeben, muss man seine {{Pfad|Generische Typen|Wrapperklasse}} benutzen.  


Dies ist vor allem bei Strings wichtig zu wissen, da Strings in Java nicht zu den primitiven Datentypen gehören. Daher werden sie immer als Referenz übergeben. (Strings haben in Java eine Sonderstellung, die manchmal zu unvorhersehbaren Fehlern führen kann. Mehr dazu kannst du unter <ref>http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_04_002.htm#mj1ce18a66f5cc0a95bbe689a9d8271a3d</ref> lesen.)
Dies ist insbesondere bei Strings wichtig zu wissen, da Strings in Java nicht zu den primitiven Datentypen gehören. Daher werden sie immer als Referenz übergeben. (Strings haben in Java eine Sonderstellung, die manchmal zu unvorhersehbaren Fehlern führen kann. Mehr dazu kannst du unter <ref>http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_04_002.htm#mj1ce18a66f5cc0a95bbe689a9d8271a3d</ref> lesen.)


Andere Programmiersprachen erlauben das explizite Festlegen, welche Aufrufart verwendet werden soll. Dort können auch primitive Datentypen als Referenz übergeben werden.  
Andere Programmiersprachen erlauben das explizite Festlegen, welche Aufrufart verwendet werden soll. Dort können auch primitive Datentypen als Referenz übergeben werden.  


In wieder anderen Programmiersprachen sind die beschriebenen Konzepte irrelevant, da Änderungen an Variablen nicht erlaubt sind und eine Unterscheidung der Aufrufarten keinen Sinn macht (vgl. [[wikipedia:Funktionale Programmierung|Funktionale Programmierung]]).
In wieder anderen Programmiersprachen sind die beschriebenen Konzepte irrelevant, da Änderungen an Variablen nicht erlaubt sind und eine Unterscheidung der Aufrufarten nicht sinnvoll ist (vgl. [[wikipedia:Funktionale Programmierung|Funktionale Programmierung]]).


<references/>
<references/>

Version vom 7. Februar 2022, 23:07 Uhr

Methoden sind eine Reihe von Anweisungen, die mehrfach wiederverwendet werden können. Im Sinne der strukturieren Zerlegung können so Teilprobleme gelöst werden und zur Lösung von komplexeren Problemen kombiniert werden.

In einem Zeichenprogramm könnte es etwa eine Methode public void zeichneQuadrat() geben. Sie würde immer das gleiche Quadrat zeichnen. Das wäre wenig sinnvoll, denn eigentlich sollen ja beliebige Quadrate gezeichnet werden können. (Also mit beliebig großer Kantenlänge.)

Parameter

Damit man nicht für alle möglichen Quadrate eigene Methoden schreiben muss (was gar nicht möglich ist, da es theoretisch unendlich viele Quadrate gibt), kann man der Methode mit einem Parameter sagen, wie groß das Quadrat werden soll.

public void zeichneQuadrat( double pKantenlaenge )

In den vorhergegangenen Schritten sind solche Parameter schon öfter aufgetaucht. Sie sind Variablen, die im Methodenkopf deklariert, aber erst beim Aufruf der Methode mit einem Wert initialisiert werden.

Die Paramtervariable ist dann im gesamten Methodenrumpf gültig und kann wie andere Variablen benutzt werden.

Eine Methode kann auch mehr als einen Parameter haben. Die Methode von oben könnte zu zeichneRechteck verallgemeinert werden und zwei Parameter für die beiden Kantenlängen bekommen:

public void zeichneRechteck( double pKanteA, double pKanteB )

Für die Bezeichner von Parametern gelten dieselben Vorgaben wie für die von Variablen und Methoden. Um sie leichter von lokalen Variablen innerhalb des Methodenrumpfes unterscheiden zu können, benutzt man häufig ein kleines "p" als Präfix. Dies ist aber nur eine Absprache unter Entwicklern, um den Quellcode besser lesbar zu machen. Man könnte als Bezeichner auch xTezU oder sonst einen Unsinn benutzen.

Rückgabetypen

Mit Parametern kannst du "etwas in die Methode hineingeben" und so die Ausführung des Algorithmus beeinflussen (abhängig von der Eingabe machen). Umgekehrt kannst du auch "etwas aus der Methode herausgeben" und für weitere Verarbeitungen nutzen. Die Methode hat dann eine Rückgabe von einem bestimmten Rückgabetyp.

Hat eine Methode keine Rückgabe, dann wird als Rückgabetyp void angegeben.

public void einAuftrag()
Icon Info.png

Wir nennen Methoden ohne Rückgabe Aufträge, da sie den Auftrag haben einen Algorithmus auszuführen. Methoden mit Rückgabe nennen wir Anfragen, da der Aufrufende erwartet, eine bestimmte Antwort zu bekommen.


Bei Methode mit Rückgabe wird statt void der Datentyp des Rückgabewertes angegeben.

public int eineAnfrage()

Wie du siehst kann nur genau ein Rückgabetyp notiert werden. Auch wenn Methoden mehrere Parameter haben dürfen, können sie maximal einen Rückgabewert zurückgeben.

Rückgaben implementieren

Hast du im Methodenkopf den passenden Rückgabetyp angegeben und die Methode so als Anfrage markiert, dann muss innerhalb der Methode nur noch der passende Wert zurückgegeben werden.

Dazu gibt es das Schlüsselwort return.

public int gibVier() {
  return 4;
}

Jede Anfrage muss mit einem return enden, das einen Wert des passenden Rückgabetyps zurückgibt. Das bedeutet auch, dass bei bedingten Anweisungen (if-Anweisungen) beide Alternativen am Ende zu einem return führen müssen.

public boolean istKleinerAlsVier( int pZahl ) {
  if( pZahl < 4 ) {
    return true;
  } else {
    return false;
  }
}

Die Methode aus dem letzten Beispiel kannst du auch ohne bedingte Anweisung schreiben. Der Vergleich pZahl < 4 ergibt einen Wahrheitswert (boolean). Ist dieser Wert true, dann wird true zurückgegeben. Ist er false, dann wird false zurückgegeben. Also könntest du auch direkt das Ergebnis des Vergleichs zurückgeben:

public boolean istKleinerAlsVier( int pZahl ) {
  return pZahl < 4;
}

Aufrufarten bei Parametern

Wird eine Methode mit Parametern aufgerufen, dann wird die Parametervariable mit einem Wert initialisiert. Je nachdem, welchen Datentyp der Parameter hat, wird eine von zwei Arten der Initialisierung benutzt.

Call-by-value

Handelt es sich um einen primitiven Datentyp, dann wird der Wert, mit dem die Methode aufgerufen wird als Kopie an die Methode übergeben. Änderungen an der Paramtervariablen wirken sich nur innerhalb des Methodenrumpfes aus, nicht aber außerhalb der Methode.

Man spricht im Deutschen von einem Wertparameter.

Call-by-reference

Handelt es sich um eine Objektreferenz, dann wird auch nur eine Referenz übergeben. Wie im Schritt Referenzen beschrieben wird, handelt es sich dabei um einen Zeiger auf ein Objekt im Speicher. Änderungen an diesem Objekt wirken sich überall im Programm aus, nicht nur innerhalb der Methode.

Man spricht im Deutschen von einem Referenzparameter.

Weiterführende Informationen

In Java wird durch den Typ des Parameters die Aufrufart bestimmt. Primitive Typen werden immer als Wertparameter, Objekte als Referenzparameter übergeben. Um einen primitiven Typ als Referenz zu übergeben, muss man seine Wrapperklasse benutzen.

Dies ist insbesondere bei Strings wichtig zu wissen, da Strings in Java nicht zu den primitiven Datentypen gehören. Daher werden sie immer als Referenz übergeben. (Strings haben in Java eine Sonderstellung, die manchmal zu unvorhersehbaren Fehlern führen kann. Mehr dazu kannst du unter [1] lesen.)

Andere Programmiersprachen erlauben das explizite Festlegen, welche Aufrufart verwendet werden soll. Dort können auch primitive Datentypen als Referenz übergeben werden.

In wieder anderen Programmiersprachen sind die beschriebenen Konzepte irrelevant, da Änderungen an Variablen nicht erlaubt sind und eine Unterscheidung der Aufrufarten nicht sinnvoll ist (vgl. Funktionale Programmierung).