Methoden bzw. Funktionen
Unser Tagebuch Programm ist wieder gewachsen und neigt dazu, trotz
der Kommentare, schwierig lesbar zu werden. Um dieses Problem wieder
inden Griff zu bekommen, wollen wir es in Methoden aufteilen. Ein
weiterer Vorteil liegt darin, dass wir einzelne Teile des Programms
später in einem anderen Kontext wieder verwenden können.
Wie im Buch
"Hallo Welt programmieren, compilieren und ausführen in der Konsole" beschrieben, ist eine Methode ein Abschnitt im Quelltext des Programms,
mit klar definierten Eingaben und einem Rückgabetyp. Es ist üblich im
Umfeld von objektorientierten Sprachen von Methoden zu sprechen. Bei den
übrigen Sprachen spricht man von Funktionen und meint prinzipiell das
Gleiche.
Bei der Deklaration unserer Main-Methode
hatten wir eine ganz klare Vorgabe, wie diese auszusehen hat. Es musste
public static void main(String[] args) {} geschrieben werden. Diese
Beschreibung, die sogenannte Signatur, ist für die Main-Methode
festgelegt. Die Einzige erlaubte Abweichung ist die Ergänzung throws
Exception die wir Nachträglich eingefügt haben.
Aber
was sagen die einzelnen Worte der Signatur eigentlich? Das Schlüsselwort
public bezieht sich auf die Sichtbarkeit der Methode. Es sagt aus, dass
die Methode überall im Programm verwendet werden dürfte. Wir wollen an
dieser Stelle nicht genauer auf Sichtbarkeiten eingehen. Sie sind ein
wichtiger Bestandteil der objektorientierten Programmierung. Für uns
genügt es, wenn wir bei jeder Methode public verwenden.
Auch
das Schlüsselwort static stammt aus der objektorientierten
Programmierung. Es weist darauf hin, dass die Methode nicht an eine
Instanz einer Klasse gebunden ist. Sie kann daher aufgerufen werden
ohne, dass vorher eine Instanz von unserer Klasse erstellt werden muss.
Bei uns sollen alle Methoden static sein, um der Komplexität der
Objektorientierung ersteinmal aus dem Wege zu gehen.
Als
nächstes geben wir den Rückgabetyp der Methode an. Beim Beispiel der
Main-Methode ist der Rückgabetyp void, das heißt es soll nichts zurück
gegeben werden. Wir können bei unseren Methoden jeden beliebigen Typ
verwenden. Wenn wir einen anderen Typ als void angeben, müssen wir
zwingend einen Wert zurückgeben.
Als nächstes sieht
die Signatur den Namen der Methode vor. In unserem Beispiel “main”. Bei
selbst definierten Methoden kann der Name frei gewählt werden. Es
empfiehlt sich natürlich einen möglichst aussagekräftigen Namen zu
wählen. Ein mögliches Benennungsverfahren ist die Kombination aus einem
Verb und einem Nomen. So lässt sich gut ausdrücken, was die Methode tun
soll. Beispiele wären “leseDatei”, “pruefeEingabe” oder “berechneSumme”.
Es ist in Java üblich, dass Methodennamen mit einem Kleinbuchstaben
beginnen und jedes neue Wort mit einem Großbuchstaben aber ohne
Trennzeichen angehängt werden. Der sogenannte Camel Case. Es ist
außerdem üblich Umlaute und ß zu ersetzen weil diese bei der Weitergabe
des Codes, an andere Programmierer, öfter Schwierigkeiten verursachen.
Der
nächste Abschnitt der Signatur ist die Parameterliste, welche in runden
Klammern steht. Parameter sind Variablen, die beim Aufruf der Methode
übergeben werden müssen. Für eine leere Liste schreibt man nur die
Klammern “()”. Benötigt man mehrere Parameter, so werden die einzelnen
Parameter durch Kommata getrennt. Es wird vor jedem Parameter der Typ
geschrieben. Eine Methode “schreibeSumme” mit zwei Zahlen als Eingabe
könnte wie folgt deklariert werden:
public static void schreibeSumme(int zahl1, int zahl2) {
System.out.println(zahl1 + zahl2);
}
Ein Aufruf dieser Methode könnte z.B. so aussehen schreibeSumme(1, 2);
Anstatt die Summe auszugeben kann sie auch zurückgegeben werden um sie im weiteren Programmablauf verwenden zu können. Hierfür muss der Rückgabetyp der Methode richtig definiert werden und es muss ein “return” definiert werden. Mit dem “return” wird festgelegt, welcher Wert zurück gegeben werden soll.
public static void berechneSumme(int zahl1, int zahl2) {
return zahl1 + zahl2;
}
Jeder Code-Pfad soll mit einem “return” enden. Code, der nach einem “return” folgt, wird nicht mehr ausgeführt.
Als letzter Teil der Signatur kann eine ‘throws’ Anweisung mit einem Fehlerdatentyp angegeben werden. Ersteinmal soll es ausreichen bei jeder Methodendeklaration “throws Exception” anzugeben. Wir werden im Abschnitt “Fehlerbehandlung” darauf genauer eingehen.
Wir haben jetzt alles was wir brauchen um unser Beispiel in mehrere Methoden aufzuteilen. Unsere Main-Methode soll dabei nur noch die einzelnen Aktionen starten. Als erstes prüft sie den Namen des Benutzers. Erst, wenn der Name der Richtige ist, werden Daten aus der Datei geladen. Dies soll in der Methode leseAusDatei() geschehen. Sie bekommt als Parameter eine Datei. Existiert die Datei so wird der Inhalt zurückgegeben, sonst nur ein leerer String.
Die zweite Methode leseEingaben() soll den Nutzer auffordern etwas einzugeben und die Eingaben zurück geben. Die dritte Methode schreibeDaten() gibt nichts zurück. Sie speichert den übergebenen String in die Datei. Dieses Programm kann wie folgt umgesetzt werden:
import java.io.File;
import java.io.PrintWriter;
import java.util.Scanner;
public class Tagebuch {
public static void main(String[] args) throws Exception {
System.out.println("Wie heißt du?");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
if (name.equals("Jan")) {
System.out.println("Hallo " + name + "!");
File datei = new File("tagebuch-" + name + ".txt");
String text = leseAusDatei(datei);
text .= leseEingaben(scanner);
schreibeDaten(text, datei);
} else {
System.out.println("Der Benutzer ist abgelehnt.");
}
scanner.close();
}
public static String leseAusDatei(File datei) throws Exception {
String text = "";
if (datei.exists()) {
Scanner scnr = new Scanner(datei);
while (scnr.hasNextLine()) {
text += scnr.nextLine() + "\n";
}
scnr.close();
}
System.out.println("Geladener Text: " + text);
return text;
}
public static String leseEingaben(Scanner scanner) {
String text = "";
System.out.println("Bitte Text eingeben. Zum Beenden 'quit' eingeben.");
// Schleife zum Einlesen des Textes
while (true) {
String eingabe = scanner.next();
// "quit" beendet die Schleife
if (eingabe.equals("quit")) {
break;
}
text += eingabe;
}
System.out.println("Eingegeben wurde: " + text);
return text;
}
public static void schreibeDaten(String text, File datei) throws Exception {
PrintWriter printWriter = new PrintWriter(datei);
printWriter.print(text);
printWriter.close();
}
}