Programmiertechnik Klassenmethoden Prof. Dr. Oliver Haase Oliver Haase Hochschule Konstanz 1
Motivation Programm zur Berechung von public class Eval1 { public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.print("n:"); int n = scanner.nextInt(); System.out.print("x:"); double x = scanner.nextDouble(); double f_x_n = 1.0; for ( int i = 0; i < 2*n; i++ ) { f_x_n *= x; } f_x_n += n*n - n*x; System.out.println("f(x,n) = " + f_x_n); } } Oliver Haase Hochschule Konstanz 2
Motivation Aufgabe : Erweitere das Programm so, dass der Benutzer statt eines Wertes x die Randwerte a , b eines Intervalls [ a , b ] eingibt und das Programm die folgende Berechnung anstellt: berechne f am linken Randpunkt a des Intervalls; berechne f am rechten Randpunkt b des Intervalls; berechne f am Mittelpunkt des Intervalls; gib den Mittelwert der drei Funktionswerte aus. Oliver Haase Hochschule Konstanz 3
Motivation Erste Lösung: public class Eval2 { public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.print("n:"); int n = scanner.nextInt(); System.out.print("a:"); double a = scanner.nextDouble(); System.out.print("b:"); double b = scanner.nextDouble(); double m = (a + b) / 2.0; double f_a_n = 1.0; for ( int i = 0; i < 2*n; i++ ) { f_a_n *= a; } Oliver Haase Hochschule Konstanz 4
Motivation f_a_n += n*n - n*a; double f_b_n = 1.0; for ( int i = 0; i < 2*n; i++ ) { f_b_n *= b; } f_b_n += n*n - n*b; double f_m_n = 1.0; for ( int i = 0; i < 2*n; i++ ) { f_m_n *= m; } f_m_n += n*n - n*m; double mittel = (f_a_n + f_m_n + f_b_n) / 3; System.out.println("Mittelwert: " + mittel); } } Oliver Haase Hochschule Konstanz 5
Motivation Beobachtung : Programm lang und unübersichtlich hauptsächlich wegen dreimaliger gleicher Berechnung der Funktion f Lösungsidee : gliedere Berechnung von f aus als Routine , Unterprogramm , Funktion, Methode , so dass derselbe Code nicht mehrfach hingeschrieben werden muss. Oliver Haase Hochschule Konstanz 6
Was ist eine Methode? Ein Stück Programmcode, dem ein Namen gegeben wird, unter dem es aufgerufen werden kann. Eine Methode kann Parameter ( Argumente ) enthalten, die beim Aufruf durch Werte ersetzt werden. Eine Methode kann ein Ergebnis zurückliefern. Ähnlich einer mathematischen Funktion, die einen oder mehrere Werte (Parameter) auf ein Ergebnis abbildet. Es gibt Klassen- und Instanzmethoden . Hier und jetzt werden Klassenmethoden behandelt. Oliver Haase Hochschule Konstanz 7
Was ist eine Klassenmethode? Syntaxregel public static <ErgebnisTyp> <MethodenName>(<FormaleParameter>) { // Methodenrumpf: hier den // Programmcode einfuegen } < Ergebnistyp >: Typ des Ergebnisses, z.B. int oder double . Falls Methode kein Ergebnis liefert, dann void . < MethodenName >: Selbstgewählter Methodenname (keine reservierten Wörter!) < FormaleParameter >: Kommaliste von Variablendeklarationen der Form <Typ> <Name> (z.B. int n, double x ). Enthält sog. formale Parameter ( formale Argumente ). Die erste Zeile einer Methode wird Methodenkopf oder Signatur genannt. Oliver Haase Hochschule Konstanz 8
main -Methode Beobachtung : Die bereits vielfach verwendete Zeile public static void main(String[] args) { ist der Kopf der main -Methode. Die main-Methode (Hauptmethode) ist die erste Methode eines Programmes ( genauer : einer Klasse), die ausgeführt wird. liefert kein Ergebnis (wem auch?) erhält ein Feld von Strings mit dem Namen args als Parameter. (Dieses Feld kann dazu genutzt werden, dem Programm beim Start Argumente mitzugeben, dazu später mehr.) Oliver Haase Hochschule Konstanz 9
Beispiel-Methode Aufgabe : Programmiere eine Methode für die Funktion f vom Anfang: Oliver Haase Hochschule Konstanz 10
Beispiel-Methode Aufgabe : Programmiere eine Methode für die Funktion f vom Anfang: Methodenkopf: < Rueckgabetyp > : double f < MethodenName > : double x, int n < FormaleParameter >: Oliver Haase Hochschule Konstanz 11
Beispiel-Methode Aufgabe : Programmiere eine Methode für die Funktion f vom Anfang: Methodenkopf: < Rueckgabetyp > : double < MethodenName > : f double x, int n < FormaleParameter >: public static double f(double x, int n) { Oliver Haase Hochschule Konstanz 12
Beispiel-Methode Methodenrumpf: public static double f(double x, int n) { double ergebnis = 1.0; for ( int i = 0; i < 2*n; i++ ) { ergebnis *= x; } ergebnis += n*n - n*x; return ergebnis; } Oliver Haase Hochschule Konstanz 13
return-Anweisung Die Anweisung return ergebnis; beendet die Methode und gibt den Wert der Variablen ergebnis als Methodenergebnis zurück. Der Typ von ergebnis muss zuweisungskompatibel mit dem Rückgabetyp der Methode sein. Hat die Methode den Rückgabetyp void , so steht return; für das sofortige Beenden der Methode. Als letzte Zeile kann diese Anweisung fehlen. Die return -Anweisung funktioniert auch für Literale und arithmetische Ausdrücke, z.B. return ergebnis + n*n - n*x; Oliver Haase Hochschule Konstanz 14
return-Anweisung Ein Methodenrumpf kann auch mehrere return -Anweisungen enthalten: public static int fakultaet(int n) { if ( n == 0 ) { return 1; } for ( int i = n -1; i > 0; i-- ) { n = n * i; } return n; } Oliver Haase Hochschule Konstanz 15
Methodenaufruf Syntaxregel <MethodenName>(<AktuelleParameter>) <MethodenName> : Name der aufzurufenden Methode <Aktuelle Parameter> : Kommaliste von Werten, je einer pro formalem Parameter, mit richtigem Typ, in der richtigen Reihenfolge. Werte können Variablen, Literale oder Ausdücke sein. Methodenaufruf ist ein elementarer Ausdruck ; durch ein nachgestelltes Semikolon wird er zur Ausdrucksanweisung . Oliver Haase Hochschule Konstanz 16
Methodenaufruf Methodenaufruf liefert in der Regel ein Ergebnis; Ausnahme : Methode mit Rückgabetyp void . Beispiele für Methodenaufrufe : double y = f(x,n); double z = f(y,3) + 3*x; int fak = fakultaet(4); Nach dem Aufruf wird der Ergebniswert für den Aufruf eingesetzt und damit weitergerechnet. Oliver Haase Hochschule Konstanz 17
Eval – die 3. und letzte Variante public class Eval3 { public static double f(double x, int n) { double ergebnis = 1.0; for ( int i = 0; i < 2*n; i++ ) { ergebnis *= x; } ergebnis += n*n - n*x; return ergebnis; } Oliver Haase Hochschule Konstanz 18
Eval – die 3. und letzte Variante public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.print("n: "); int n = scanner.nextInt(); System.out.print("a: "); double a = scanner.nextDouble(); System.out.print("b: "); double b = scanner.nextDouble(); double m = (a + b) / 2.0; double f_a_n = f(a, n); double f_b_n = f(b, n); double f_m_n = f(m, n); double mittel = (f_a_n + f_m_n + f_b_n) / 3; System.out.println("Mittelwert: " + mittel); } } Oliver Haase Hochschule Konstanz 19
Parameterübergabe Bei jedem Methodenaufruf wird: für jeden formalen Parameter eine neuer Speicherplatz angelegt; die Werte der aktuellen Parameter dort hinein kopiert ; diese Speicherplätze der Methode zur Verfügung gestellt. Änderungen an Parameterwerten in der Methode haben keinen Effekt auf das Hauptprogramm! Diese Art der Parameterübergabe heißt Werteübergabe ( call by value ) Oliver Haase Hochschule Konstanz 20
Parameterübergabe Beispiel : Das folgende Programm public class AufrufTest { public static void unterprogramm(int n) { n *= 5; System.out.println("n = " + n); } public static void main(String[] args) { int n = 7; System.out.println("n = " + n); unterprogramm(n); System.out.println("n = " + n); } } erzeugt die Ausgabe: Konsole n = 7 n = 35 n = 7 Oliver Haase Hochschule Konstanz 21
Parameterübergabe Speicherabbild für das Beispielprogramm: lokale Variable der main Methode main n 7 unterprogramm formale Variable n 7 35 nur innerhalb des Unterprogramms bekannt Oliver Haase Hochschule Konstanz 22
Übergabe von Referenzdatentypen geändertes AufrufTest -Programm (Integerfeld statt Integer als Übergabeparameter): public class AufrufTest2 { public static void unterprogramm(int[] n) { n[0] *= 5; System.out.println("n[0] = " + n[0]); } public static void main(String[] args) { int n[] = {7}; System.out.println("n[0] = " + n[0]); unterprogramm(n); System.out.println("n[0] = " + n[0]); } } erzeugt die Ausgabe: Konsole n = 7 ??? n = 35 n = 35 Oliver Haase Hochschule Konstanz 23
Übergabe von Referenzdatentypen Auch bei Referenzdatentypen (Feldern, Objekten) wird der Wert des aktuellen Parameters kopiert, aber Der Wert eines Referenzdatentyps ist ein Verweis auf das eigentliche Datum. Speicherabbild : Aufrufschachteln (Methodenstack) Freispeicher (Heap) main n 7 35 unterprogramm n Oliver Haase Hochschule Konstanz 24
More recommend