2.7.1 Parameter und Parameterübergabe
Eine Methode definiert einen bestimmten ALGORITHMUS - das ist im Wesentlichen ein immer gleichbleibender Programmablauf. Sehr oft soll dieser Algorithmus bei mehrmaligem Aufruf der Methode jeweils mit unterschiedlichen Werten durchgeführt werden. Diese Werte werden im Allg. außerhalb der Methode definiert.
- Definitionen:
- Ein PARAMETER ist ein konstanter Wert, der außerhalb einer Methode festgelegt wird und der den Methoden-Algorithmus nicht beeinflusst (sehr wohl beeinflusst er aber das Ergebnis der Methode im Allg. ganz wesentlich).
Die Parameterwerte müssen somit immer beim Aufruf einer Methode von außen an die Methode übergeben werden.
In der Methodendefinition müssen für die Parameterwerte Platzhalter definiert werden, die dann unmittelbar vor jedem Aufruf der Methode durch die richtigen Werte bzw. Variablen ersetzt werden.
- Die AKTUELLEN PARAMETER sind die Werte bzw. Variablen, mit denen die Methode nach dem Aufruf tatsächlich durchgeführt wird. Aktuelle Parameter nennt man auch ARGUMENTE.
- Die (FORMALEN) PARAMETER sind in der Methodendefinition einfach die Platzhalter für die aktuellen Parameter des Methodenaufrufs.
- Die AKTUELLEN PARAMETER sind die Werte bzw. Variablen, mit denen die Methode nach dem Aufruf tatsächlich durchgeführt wird. Aktuelle Parameter nennt man auch ARGUMENTE.
Man unterscheidet die folgenden Arten von Parametern:
- EINGANGSPARAMETER
- Der Wert dieses Parameters beeinflusst das Ergebnis einer Methode ganz wesentlich, aber dieser Wert wird durch die Methode nicht geändert.
- AUSGANGSPARAMETER
- Dieser Parameter dient nur zur Speicherung eines Methodenergebnisses, d.h., der Wert eines solchen Parameters wird durch die Methode geändert (wobei der ursprüngliche Wert für die Methode völlig irrelevant ist).
- DURCHGANGSPARAMETER
- Ein solcher Parameter ist sowohl Eingangs- als auch Ausgangsparameter.
Eine wichtige Aufgabe einer Methode ist die PARAMETERÜBERGABE beim Aufruf der Methode.
Man unterscheidet 2 Arten der Parameterübergabe:
- WERTÜBERGABE ("call by value") und
- REFERENZ- oder ADRESSÜBERGABE ("call by reference" bzw. "call by address").
Bei der Wertübergabe existiert in der aufgerufenen Methode für den formalen Parameter ein eigener Speicherplatz, in den der Wert (= Inhalt) des entsprechenden Arguments beim Aufruf der Methode übertragen (d.h. kopiert) wird. Bei der Rückkehr in die rufende Methode erfolgt aber keine Übertragung mehr! Der Speicherplatz des Arguments der rufenden Methode ist absolut geschützt. Die aufgerufene Methode kann zwar den Inhalt eines Parameters ändern - dies bewirkt aber keine Änderung des Inhalts des entsprechenden Arguments (weil ja nur eine Speicherplatzkopie bearbeitet wird). Diese Art der Parameterübergabe kann nur für Eingangsparameter verwendet werden.
- Bem.:
- Ist der Parameter ein Referenztyp, kann zwar der Wert des Arguments (dieser Wert ist eine Adresse - siehe Kap.2.2.1) in der Methode nicht geändert werden, allerdings steht in der Methode das referenzierte Originalobjekt zur Verfügung, weil ja sowohl das Argument als auch der Parameter an dasselbe Objekt gebunden sind (Originalspeicherplatz des Arguments und Speicherplatzkopie des Parameters haben denselben Inhalt). Daher kann in diesem Fall der Zustand des Originalobjekts in der Methode sehr wohl geändert werden!
Bei der Referenzübergabe wird beim Aufruf der Methode nur die Speicherplatzadresse des Arguments (der rufenden Methode) in den formalen Parameter der aufgerufenen Methode übertragen. Diese arbeitet danach direkt mit dem Originalspeicherplatz des Arguments. Jede Änderung eines Parameters bedeutet eine Änderung des Arguments! Diese Art der Parameterübergabe muss für Ausgangs- und Durchgangsparameter verwendet werden.
Die Art der Parameterübergabe ist völlig unabhängig vom Typ des zu übergebenden Parameters (Wert- und Referenztyp - siehe Kap.2.2.1)!
Zusammenfassend gibt es demnach 4 verschiedene Möglichkeiten bei der Parameterübergabe:
- Wertübergabe eines Wertetyps
- Wertübergabe eines Referenztyps (diese Möglichkeit wird häufig mit einer Referenzübergabe verwechselt, weil die praktischen Auswirkungen dieser beiden Möglichkeiten einander entsprechen - siehe obenstehende Bemerkung)
- Referenzübergabe eines Wertetyps
- Referenzübergabe eines Referenztyps (diese Möglichkeit bietet kaum praktischen Nutzen und kann im Allg. problemlos durch eine Wertübergabe eines Referenztyps ersetzt werden)
2.7.1.1 Parameterübergabe in Java, C# und Smalltalk
In Java gibt es nur die Wertübergabe.
- Bem.:
- Es gibt in Java keine Referenzübergabe!
- Manchmal wird fälschlicherweise die Wertübergabe eines Referenztyps in Java als Referenzübergabe angesehen (siehe auch die diesbezüglichen Erklärungen zuvor)!
In Smalltalk gibt es nur die Referenzübergabe, wobei jedoch die formalen Parameter in einer Methode als Konstante behandelt werden, d.h. sie können in einer Methode nicht geändert werden - die praktischen Auswirkungen entsprechen somit einer Wertübergabe.
In C# und in C++ gibt es sowohl Wertübergabe als auch Referenzübergabe.
- Bem.:
- In C++ werden die Begriffe "Adressübergabe" und "Referenzübergabe" nicht als Synonyme verwendet, weil manchmal die Wertübergabe eines Zeigers (der ja eine Adresse enthält) als sogenannte "C-Adressübergabe" bezeichnet wird (tatsächlich ist diese "C-Adressübergabe" aber nichts anderes als eine Wertübergabe!).
Beispiel zum Testen der Parameterübergabe (Klasse Person (Java) bzw. Person (C#)):
Java (nur Wertübergabe möglich):
Klasse ParameterTesten |
---|
/* * ParameterTesten.java */ package at.beringer.oopBuch.einfacheBsp; /** Applikation zum Testen der Parameterübergabe mit Call By Value. <hr /> @since Mai 2013 @see Person @see ProgrammParameterTesten @author Beringer Alfred */ public class ParameterTesten { // ------------------------------------------------------------------------- // Instanzmethoden // ------------------------------------------------------------------------- /** Start-Methode zum Testen der Applikation. */ public void start() { Person p = new Person(1980, 'M'); p.aendernVorname("Hugo"); testen(p); System.out.println("Danach noch immer: " + p.heisst()); } /** ------------------------------------------------------------------------ Methode mit 1 Parameter - dieser Parameter ist ein Referenztyp. Der Inhalt des Arguments wird beim Aufruf der Methode in den Parameter 'param' kopiert (call by value!). Dieser Inhalt ist eine Referenz auf ein 'Person'-Objekt. D.h.: Die beiden Variablen (Argument und Parameter) sind an ein und dasselbe 'Person'-Objekt gebunden. Es gibt also während der Methodendurchführung 2 Referenzen auf 1 einziges 'Person'-Objekt (daher könnte in der Methode dieses 'Person'-Objekt modifiziert werden - über die Parameterreferenz). Die Bindung des Parameters an dieses eine 'Person'-Objekt kann in der Methode aufgehoben werden, NICHT aber die Bindung des Arguments!!! @param param Referenz auf ein 'Person'-Objekt */ public void testen(Person param) { Person pp = new Person(2013, 'M'); pp.aendernVorname("Maxi"); param = pp; // nur Referenzkopie geändert! System.out.println(" In der Methode: " + param.heisst()); } } |
Java - Programmklasse
Programmklasse ProgrammParameterTesten |
---|
/* * ProgrammParameterTesten.java */ package at.beringer.oopBuch.einfacheBsp; /** Testen Parameterübergabe. <hr /> @since Mai 2013 @see ParameterTesten @author Beringer Alfred */ public class ProgrammParameterTesten { // ------------------------------------------------------------------------- /** Der Einstiegspunkt für die Anwendung. @param args Kommandozeilenparameter */ public static void main(String[ ] args) { ParameterTesten test = new ParameterTesten(); test.start(); } } |
C# (Referenzübergabe mit dem Schlüsselwort ref
):
Klasse ParameterTesten |
---|
/* * ParameterTesten.cs */ using System; namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Applikation zum Testen der Parameterübergabe mit Call By Reference. <p> Seit: Mai 2013 </p> <seealso cref="Person" /> <seealso cref="Beringer.oopBuch.EinfacheBspProgramme.ProgrammParameterTesten"/> Autor: Beringer Alfred </summary> */ public class ParameterTesten { /** -------------------------------------------------------------------- <summary> Start-Methode zum Testen der Applikation. </summary> */ public void Start() { Person p = new Person(1980, 'M'); p.AendernVorname("Hugo"); Testen(ref p); Console.WriteLine("Danach jetzt doch: " + p.Heisst()); #if DEBUG Console.ReadLine(); #endif } /** -------------------------------------------------------------------- </summary> Methode mit 1 Parameter - dieser Parameter ist ein Referenztyp. Die Adresse des Arguments wird beim Aufruf der Methode an die Methode übergeben (call by reference!). Daher ist der Parameter 'param' identisch mit dem Argument. D.h.: Wird der Parameter geändert, so wird gleichzeitig das Argument geändert. Wird die Bindung des Parameters an das 'Person'-Objekt in der Methode aufgehoben, ist automatisch auch die Bindung des Arguments aufgehoben!!! </summary> <param name="param"> Referenz auf ein 'Person'-Objekt </param> */ public void Testen(ref Person param) { Person pp = new Person(2013, 'M'); pp.AendernVorname("Maxi"); param = pp; // Originalreferenz geändert! Console.WriteLine(" In der Methode: " + param.Heisst()); } } } |
C# - Programmklasse
Programmklasse ProgrammParameterTesten |
---|
/* * ProgrammParameterTesten.cs */ using System; namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Testen Parameterübergabe <p> Seit: Mai 2013 </p> <seealso cref="ParameterTesten" /> Autor: Beringer Alfred </summary> */ public class ProgrammParameterTesten { /** -------------------------------------------------------------------- <summary> Der Einstiegspunkt für die Anwendung. </summary> <param name="args"> Kommandozeilenparameter </param> */ public static void Main(String[] args) { ParameterTesten test = new ParameterTesten(); test.Start(); } } } |
Ausgabe in Java:
In der Methode: Maxi Danach noch immer: Hugo
Ausgabe in C#:
In der Methode: Maxi Danach jetzt doch: Maxi
- Weiter
- zu Kapitel 3
- zu den Klassenbeispielen von Kapitel 4
- zu den Java-Klassenbeispielen von Kapitel 5.19.1 (Exceptions)
- zu den Java-Klassenbeispielen von Kapitel 6 (Ein-/Ausgabe von Daten)
- zu den Java-Klassenbeispielen von Kapitel 7 (GUI)
- zu Kapitel 8 (JDBC)
- zu den C#-Klassenbeispielen von Kapitel 9.19.1 (Exceptions)
- zu den C#-Klassenbeispielen von Kapitel 10 (Ein-/Ausgabe von Daten)
- zu Kapitel 12 (PL/I)
- zu Kapitel 13 (Reservierte Worte)
- zu den Klassenbeispielen von Kapitel 4
- Zurück
- zum Anfang dieses Kapitels
- zum Inhaltsverzeichnis
- zu Kapitel 1
- zu den Klassenbeispielen von Kapitel 2
- zum Inhaltsverzeichnis
- Zur
- Java-Dokumentation der Java-Beispiele