Oliver Haase Hochschule Konstanz 1
Programmiertechnik
Klassenmethoden
- Prof. Dr. Oliver Haase
Programmiertechnik Klassenmethoden Prof. Dr. Oliver Haase Oliver - - PowerPoint PPT Presentation
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
Oliver Haase Hochschule Konstanz 1
Oliver Haase Hochschule Konstanz 2
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 3
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 4
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 5
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 6
Beobachtung:
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 7
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 8
public static <ErgebnisTyp> <MethodenName>(<FormaleParameter>) { // Methodenrumpf: hier den // Programmcode einfuegen }
Syntaxregel
<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 9
Beobachtung: Die bereits vielfach verwendete Zeile
public static void main(String[] args) {
ist der Kopf der main-Methode. Die main-Methode (Hauptmethode)
ausgeführt wird.
Feld kann dazu genutzt werden, dem Programm beim Start Argumente mitzugeben, dazu später mehr.)
Oliver Haase Hochschule Konstanz 10
Aufgabe: Programmiere eine Methode für die Funktion f vom Anfang:
Oliver Haase Hochschule Konstanz 11
Aufgabe: Programmiere eine Methode für die Funktion f vom Anfang: Methodenkopf: <Rueckgabetyp> : <MethodenName> : <FormaleParameter>: double f double x, int n
Oliver Haase Hochschule Konstanz 12
Aufgabe: Programmiere eine Methode für die Funktion f vom Anfang: Methodenkopf: <Rueckgabetyp> : <MethodenName> : <FormaleParameter>: double f double x, int n
public static double f(double x, int n) {
Oliver Haase Hochschule Konstanz 13
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 14
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 15
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 16
<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.
<MethodenName>(<AktuelleParameter>) Syntaxregel
Oliver Haase Hochschule Konstanz 17
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 18
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 19
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 20
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 21
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:
n = 7 n = 35 n = 7 Konsole
Oliver Haase Hochschule Konstanz 22
Speicherabbild für das Beispielprogramm:
n 7 35
formale Variable nur innerhalb des Unterprogramms bekannt
n 7
lokale Variable der Methode main
main unterprogramm
Oliver Haase Hochschule Konstanz 23
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:
n = 7 n = 35 n = 35 Konsole
Oliver Haase Hochschule Konstanz 24
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:
n n main unterprogramm 7 35 Aufrufschachteln (Methodenstack) Freispeicher (Heap)
Oliver Haase Hochschule Konstanz 25
Maximumsberechnung für Ganzzahlen:
public static int max(int x, int y) { return (x > y) ? x : y; }
Maximumsberechnung für Gleitkommazahlen:
public static double max(double x, double y) { return (x > y) ? x : y; }
Können beide Methoden denselben Namen haben? Ja, Java unterscheidet anhand der Parameter! "Überladen von Methoden"
Oliver Haase Hochschule Konstanz 26
überladene Methoden werden unterschieden anhand
weitere Beispiele für Maximumsfunktionen:
public static int max(int x) {…} public static int max(int x, int y, int z) {…} public static int max(double x, int y) {…} public static int max(int x, double y) {…}
Oliver Haase Hochschule Konstanz 27
Methoden werden nicht unterschieden nach
public static int max(int x1, int y1) {…} kann nicht unterschieden werden (warum?) von public static int max(int x, int y) {…}
public static double max(int x, int y) {…} kann nicht unterschieden werden von public static int max(int x, int y) {…}