Advanced Services | Erster Kontakt mit Klassen |
Ein bekannter Spruch bei Programmieren lautet "Man muß das Rad nicht neu erfinden". Das bedeutet,
man will auf Programme zurückgreifen, die bestimmte Teilprobleme lösen, die immer wieder
vorkommen und für die bereits Lösungen existieren. Schon vor der Objektorientierung gab
es Programmbibliotheken, in denen man Lösungen von Standardproblemen sammelte
und bereitstellte. Solche Unterprogramme nannte man Funktionen oder Prozeduren. Die Ausgabe auf der
Konsole mit Hilfe von Console.WriteLine() etwa ist so ein Unterprogramm, d.h. genau genommen ist
WriteLine() das Unterprogramm, der Rest des Namens ist eine Art Rahmen oder Behälter in dem
die Unterprogramme bereitgestellt werden. Man kann bei objektorientierten Sprachen Unterprogramme sammeln und ihnen
einen gemeinsamen Namen voranstellen. Sie können dann nur noch im Zusammenhang mit diesem Namen
verwendet werden. Diese Unterprogramme bilden dann eine Klasse (oder einen Teil davon). Unterprogramme,
die Teil einer Klasse sind heißen Methoden oder Memberfunktionen. Leider ist der Name Memberfunktionen
aus der Mode gekommen, denn er ist sprechender als das Wort Methode, das zudem im deutschen in den
verschiedensten Zusammenhängen verwendet wird. Unterprogramme, die keiner Klasse angehören heißen
Funktionen. In C# und Java gibt es nur Methoden. In C gibt es nur Funktionen. In C++ gibt es Funktionen und
Methoden.
Natürlich ist damit der Begriff Klasse bei weitem nicht vollständig erklärt, aber wir haben
einen wichtigen Teilaspekt erläutert.
Halbwegs vernünftige Programme erwarten eine Eingabe von Daten durch den Benutzer, die dann verarbeitet werden und zu einem Resultat führen, das dem Benutzer bekanntgegeben wird. Java ist im Grunde nicht für Konsoleingaben entworfen worden. Das ist wohl auch der Grund, warum Konsoleingaben ganz allgemein unter das Kapitel Dateiverarbeitung fallen. Es gibt in Java kein Gegenstück zur scanf()-Funktion, die ja ein Spezialfall von fscanf() ist und die jedem C-Programmierer gut bekannt ist. Auch ein Gegenstück zu cin von C++ gibt es nicht. Da Dateiverarbeitung aber kein Thema für Beginner ist, habe ich eine Hilfsklasse Stdin geschrieben, die im gewissen Sinn ein Pendant zu den Ausgaben mit System.out.println() darstellt. Ich verwende diese Klasse seit Jahren in meinen Schulungen und habe damit gute Erfahrungen gemacht.
Die Klasse Console stellt u.a. die in der Überschrift erwähnten zwei Methoden zum Einlesen von Daten von der Konsole bereit.
Readline() liest alle Eingaben als Zeichen und liefert sie als String. Es wird genau eine Zeile eingelesen.
Betätigen der ENTER-Taste beendet die Eingabe. Der Zeilenumbruch selbst wird nicht mit eingelesen.
Wir wollen diese Methode verwenden und ein Programm schreiben, das Dollar in Euro umrechnet. Dazu soll
der Benutzer den Dollarbetrag und den Umrechnungskurs eingeben und als Ergebnis den Wert in Euro
erhalten. Unser Programm sieht folgendermaßen aus.
public class DollarToEuro { public static void Main() { Console.Write("Dollarbetrag eingeben : "); // 1 string dollarString = Console.ReadLine(); // 2 Console.Write("Umrechnungskurs eingeben : "); // 3 string kursString = Console.ReadLine(); // 4 double dollar = Convert.ToDouble(dollarString); // 5 double kurs = Convert.ToDouble(kursString); // 6 double euro = dollar/kurs; // 7 Console.WriteLine("Der Betrag in Euro : " + euro); // 8 } // end Main } // end main class
Wir fordern den Benutzer dazu auf, einen Dollarbetrag einzugeben und anschließend den Umrechnungskurs.
Da ReadLine() immer Zeichenketten (Strings) liefert, müssen wir die Strings in Zahlen umwandeln.
Dazu gibt es die Hilfsklasse Convert. Sie stellt eine Vielzahl von Umwandlungsmethoden bereit. Wir
verwenden die Methode ToDouble() und erhalten so double-Variablen mit denen wir Rechnen können.
Da wir in Euroland sind, besagt der Kurs wieviel Dollar wir für einen Euro bekommen, deswegen
müsen wir den Dollarbetrag durch den Kurs teilen. Wir verzichten hier auf eine Deklaration der
Variablen am Anfang des Blocks und führen sie an der Stelle ein, wo wir sie brauchen. Das Programm
besteht fast nur aus Aufrufen von Methoden, nur die Zuweisung // 7 ist eine Berechnung.
Statt lediglich class haben wir diesmal public class geschrieben und lernen damit ein neues
reserviertes Wort kennen. Der Unterschied der beiden Varianten ist hier noch nicht erkennbar und
wird später behandelt. Hier finden Sie eine Liste der reservierten Wörter.
Hier ein Durchlauf des obigen Programms:
Dollarbetrag eingeben : 123
Umrechnungskurs eingeben : 0,9876
Der Betrag in Euro : 124,544349939247
Da Visualstudio mit einer deutschen Ländereinstellung arbeitet müssen Kommazahlen tatsächlich auch mit einem
Komma eingegegben werden.
Mit dieser Methode haben wir mehr Kontrolle über die Zeichen, die der Benutzer eingibt. Read() liest genau
ein Zeichen ein. Das eingelesene Zeichen wird als ASCII-Code Zeichen im Format int geliefert, muß also
noch in den Typ char konvertiert werden. Gibt man kein Schriftzeichen ein sondern betätigt nur die ENTER-Taste
so wird der Windows-Zeilenumbruch eingelesen. Da dieser aus den beiden Zeichen \r und \n liefert die
Methode dann nur \r. Ein Abbruch der Eingabe mit Ctrl Z liefert -1.
Das folgende Programm gibt zu dem eingegebenen Zeichen den ASCII-Code sowie das eingegebene Zeichen aus. Die
Eingabe von Ctrl Z (und ENTER) beendet das Programm.
public class ReadDemo { public static void Main() { Console.WriteLine("zeichen eingeben: "); int ch; while( (ch = Console.Read()) != -1) { Console.WriteLine("{0} {1}", ch, (char)ch); } } // end Main } // end main class
Die Ausgabe des Eurobetrages im ersten Beispiel hat 12 Stellen hinter dem Komma. Das ist entschieden
zuviel. Wir wollen das Ergebnis runden und verwenden dazu die Standardklasse Math.
Diese Klasse ist eine Sammlung von Methoden. Außerdem enthält Math noch zwei Konstanten,
die Kreiszahl pi und die Euler'sche Konstante e, die uns aber hier nicht interessieren.
Math enthält u.a. Methoden zur Berechnung des Absolutbetrages, der trigonometrischen Funktionen
und von Potenzen und Wurzeln. Zudem gibt es mehrere Rundungsmethoden. Wir wählen die Methode
static double Round(double value, int digits)
Sie erhält die zu rundende Zahl als double und die Anzahl der Nachkommastellen als int und gibt die Rundung
als Zahl vom Typ double zurück.
public class DollarToEuro2 { public static void Main() { Console.Write("Dollarbetrag eingeben : "); // 1 string dollarString = Console.ReadLine(); // 2 Console.Write("Umrechnungskurs eingeben : "); // 3 string kursString = Console.ReadLine(); // 4 double dollar = Convert.ToDouble(dollarString); // 5 double kurs = Convert.ToDouble(kursString); // 6 double euro = dollar/kurs; // 7 double gerundet = Math.Round(euro, 4); // 8 Console.WriteLine("Der Betrag in Euro : " + gerundet); // 9 } // end Main } // end main class
Eine Methode erledigt eine Teilaufgabe eines Programms. Sie kann dazu Daten aus dem Programm übergeben bekommen oder auch Daten (Ergebnisse) an das Programm zurückgeben. Im obigen Beispiel bekommt die Methode Writeline() jeweils Strings übergeben. Die Methode ReadLine() arbeitet in einer gewissen Weise genau umgekehrt, sie bekommt keine Daten aus dem Programm (leere runde Klammern !), liefert aber einen Wert an das Programm zurück, nämlich die vom Benutzer eingegebene Zahl. Natürlich gibt es auch Methoden, die Daten erhalten und Daten zurückliefern. Es gibt auch Methoden, die mehrere Daten erhalten. Die Daten, die man in den runden Klammern übergibt nennt man Parameter. Hier sind Anzahl, Typ und Reihenfolge zu beachten. Zurückgelieferte Daten werden in der Regel einer Variablen zugewiesen. Der zugewiesene Wert heißt Returnwert, sein Typ folgerichtig Returntyp. Eine Methode kann keine oder (quasi beliebig) viele Parameter erwarten. Methoden haben (bis auf einen Spezialfall, den wir hier noch außer Acht lassen) immer einen Returntyp und dazu keinen oder genau einen Returnwert. Für Methoden ohne Returnwert gibt es einen eigenen Returntyp, er heißt void . Wir fassen zusammen:
Der Returntyp void existiert nur im Zusammenhang mit Methoden. Eine Deklaration der Form void x ; existiert nicht.
Wir haben nun
Methoden aus den drei Klassen Console, Convert und Math verwendet. Der Aufruf der
Methoden folgte immer dem gleichen Schema. Man beginnt mit dem Namen der Klasse, die die Methode enthält,
setzt einen Punkt
und danach erscheint der Name der Methode. Diese Art von Aufruf einer Methode heißt statisch.
Man erkennt statische Methoden daran, daß in der Dokumentation vor dem Returntyp ein dickes s
in oranger Farbe erscheint. Statische Methoden werden immer nach dem soeben erwähnten Schema aufgerufen.
Methoden, bei denen in der Dokumentation der Buchstabe s nicht erscheint, heißt nicht statisch.
Ihr Aufruf folgt einem anderen Schema, das wir später vorstellen.
Aufrufschema für statische Methoden :
Klassenname.MethodenName()
Im Gegensatz zu Java gibt es in C# keine andere Aufrufmöglichkeit für statische Methoden.