MarktundTechnik Home-Page Previous Page TOC Index Next Page See Page



6. Tag:

Erstellen von Klassen und Anwendungen in Java

von Laura Lemay

In fast jeder bisherigen Lektion haben Sie Java-Anwendungen geschrieben. Sie haben Klassen, Instanzvariablen und Methoden erstellt und diese Anwendungen für einfache Aufgaben ausgeführt. Außerdem haben Sie sich bisher auf die grobe allgemeine objektorientierte Theorie sowie auf Einzelheiten wie Arithmetik und andere Ausdrücke konzentriert. Heute führen Sie das alles zusammen und lernen, wie und warum Klassen erstellt werden. Sie lernen in dieser Lektion folgende Grundlagen:

Definieren von Klassen

Das Definieren von Klassen ist sehr einfach. Sie haben das in den vorherigen Lektionen schon gesehen. Um eine Klasse zu definieren, verwenden Sie das Schlüsselwort class und den Namen der Klasse:

class MyClassName {

...

}

Ist die Klasse eine Subklasse einer anderen, benutzen Sie extends, um die Superklasse dieser Klasse zu bezeichnen:

class MyClassName extends mySuperClassName {

...

}

Wird dadurch eine spezifische Schnittstelle implementiert, benutzen Sie implements, um sich auf diese Schnittstelle zu beziehen:

class MyRunnableClassName implements Runnable {

...

}

Sowohl extends als auch implements wird wahlweise benutzt. Sie lernen in Woche 3 alles über die Verwendung und Definition von Schnittstellen.

Erstellen von Instanz- und Klassenvariablen

Eine Klassendefinition ohne Inhalt ist kaum sinnvoll. Normalerweise wird beim Erstellen einer Klasse etwas eingefügt, durch das sich die Klasse von ihren Superklassen unterscheidet. In jeder Klassendefinition befinden sich Deklarationen und Definitionen für Variablen oder Methoden oder beides für die Klasse und jede Instanz. In dieser Lektion lernen Sie alles über Instanz- und Klassenvariablen. Methoden sind Thema der nächsten Lektion.

Definieren von Instanzvariablen

Am 3. Tag haben Sie gelernt, wie lokale Variablen, d. h. Variablen in Methodendefinitionen, deklariert und initialisiert werden. Instanzvariablen werden zum Glück auf genau die gleiche Weise deklariert und definiert. Der einzige Unterschied ist ihre Position in der Klassendefinition. Instanzvariablen gelten als solche, wenn sie außerhalb einer Methodendefinition deklariert werden. Üblicherweise werden die meisten Instanzvariablen direkt nach der ersten Zeile der Klassendefinition definiert. Listing 6.1 zeigt als Beispiel eine einfache Definition für eine Klasse namens Bicycle, die von der Klasse PersonPoweredVehicle erbt. Diese Klassendefinition enthält vier Instanzvariablen:

Listing 6.1: Die bicycle-Klasse

1:   class Bicycle extends PersonPoweredVehicle {

2:      String bikeType;

3:      int chainGear;

4:      int rearCogs;

5:      int currentGearFront;

6:      int currentGearRear;

7:   }

Konstanten

Konstanten sind nützlich zum Setzen globaler Zustände in einer Methode oder einem Objekt oder auch zur Vergabe aussagefähiger Namen für objektweite Werte, die sich nie ändern. In Java können Sie Konstanten nur für Instanz- und Klassenvariablen, nicht aber für lokale Variablen erstellen.

Eine Konstante ist eine Variable, deren Wert sich nie ändert (was im Zusammenhang mit dem Wort »Variable« seltsam erscheinen mag).

Um eine Konstante zu deklarieren, benutzen Sie das Schlüsselwort final vor der Variablendeklaration und geben für diese Variable einen Anfangswert ein:

final float pi = 3.141592;

final boolean debug = false;

final int maxsize = 40000;

Die einzige Möglichkeit, in Java Konstanten zu definieren, ist mit dem Schlüsselwort final. #define oder const aus C und C++ sind in Java nicht verfügbar.

Konstanten sind auch nützlich zur Benennung verschiedener Zustände eines Objekts, das dann auf diese Zustände getestet werden kann. Nehmen wir beispielsweise an, Sie brauchen einen Schriftzug, die links, rechts oder zentriert ausgerichtet werden kann. Diese Werte können Sie als konstante Ganzzahlen definieren:

final int LEFT = 0;

final int RIGHT = 1;

final int CENTER = 2;

Die Variable alignment (Ausrichtung) wird dann ebenfalls als int deklariert:

int alignment;

Danach können Sie im Körper einer Methodendefinition eine der Ausrichtungen setzen:

this.alignment = CENTER;

oder auf eine bestimmte Ausrichtung prüfen:

switch (this.alignment) {

   case LEFT: // deal with left alignment

         ...

         break

   case RIGHT: // deal with right alignment

         ...

         break

   case CENTER: // deal with center alignment

         ...

         break

}

Klassenvariablen

Wie Sie in den vorherigen Lektionen gelernt haben, sind Klassenvariablen global innerhalb einer bestimmten Klasse und für alle Instanzen der jeweiligen Klasse gültig. Sie können sich Klassenvariablen noch globaler vorstellen als Instanzvariablen. Klassenvariablen eignen sich gut zur Kommunikation zwischen verschiedenen Objekten der gleichen Klasse oder zum Verfolgen globaler Zustände in bestimmten Objekten.

Um eine Klassenvariable zu deklarieren, benutzen Sie das Schlüsselwort static in der Klassendeklaration:

static int sum;

static final int maxObjects = 10;

Erstellen von Methoden

Am 2. Tag haben Sie gelernt, daß Methoden das Verhalten eines Objekts bestimmen, d. h. was passiert, wenn das Objekt erstellt wird, und welche Operationen es während seiner Lebenszeit ausführen kann. In dieser Lektion erhalten Sie eine Grundeinführung in die Methodendefinition und wie Methoden funktionieren. Morgen steigen Sie in mehr Einzelheiten über die Dinge ein, die Sie mit Methoden anstellen können.

Definieren von Methoden

Die Definition von Methoden besteht aus folgenden vier Teilen, die insgesamt die Unterschrift der Methode bilden:

Die Unterschrift einer Methode ist eine Kombination aus den Teilen ihrer Definition: Name der Methode, Objekttyp oder Grundtyp, den die Methode ausgibt, und verschiedene Parameter.

Um die heutige Lektion nicht unnötig zu verkomplizieren, habe ich zwei optionale Teile der Definition einer Methode weggelassen: einen Zugangsqualifizierer, z. B. public oder private, und das Schlüsselwort throws, das die Ausnahmen bezeichnet, die eine Methode auswerfen kann. Sie lernen diese Teile der Methodendefinition in Woche 3.

In anderen Sprachen genügt der Name der Methode (bzw. der Funktion, Subroutine oder Prozedur), um sie von anderen im Programm vorhandenen Methoden zu unterscheiden. In Java sind mehrere Methoden mit dem gleichen Namen möglich, jedoch mit einer anderen Ausgabeart und Argumentenliste. Dieses sogenannte Methoden-Overloading lernen Sie morgen kennen.

Eine einfache Methodendefinition sieht in Java so aus:

returntype methodname (type1 arg1, type2 arg2, type3 arg3...) {

   ...

}

returntype ist der primitive Typ oder die Klasse des Wertes, den die Methode ausgibt. Das kann einer der Primitivtypen, ein Klassenname oder void sein, falls die Methode überhaupt keinen Wert ausgibt.

Gibt diese Methode ein Array-Objekt aus, können die Array-Klammern entweder nach der Ausgabeart oder nach der Parameterliste eingegeben werden. Da die erste Art wesentlich übersichtlicher ist, wird sie in den heutigen Beispielen (und im gesamten Buch) angewandt:

int[] makeRange (int lower, int upper) {...}

Bei der Parameterliste einer Methode handelt es sich um verschiedene Variablendeklarationen, die durch Kommas getrennt werden und zwischen Klammern stehen. Diese Parameter bilden lokale Variablen im Körper der Methode, deren Werte Objekte oder Werte von Primitivtypen sind, die beim Aufrufen der Methode bereitgestellt werden.

Im Methodenkörper können Anweisungen, Ausdrücke, Methodenaufrufe anderer Objekte, Bedingungen, Schleifen usw. stehen - alles, was Sie in den bisherigen Lektionen gelernt haben.

Hat Ihre Methode eine Ausgabeart (d. h. die Ausgabe wurde nicht mit void deklariert), muß irgendwo im Methodenkörper ein Wert ausgegeben werden. Sie verwenden hierfür das Schlüsselwort return. Listing 6.2 zeigt ein Beispiel einer Klasse, die die Methode makeRange() definiert. makeRange()bestimmt zwei Ganzzahlen - eine obere und eine untere Grenze - und erstellt ein Array, das alle zwischen diesen Grenzen liegenden Ganzzahlen (einschließlich der Grenzwerte) enthält.

Listing 6.2: Die RangeClass-Klasse

1:   class RangeClass {

2:      int[] makeRange (int lower, int upper) {

3:         int arr[] = new int[ (upper - lower) + 1 ];

4:

5:         for (int i = 0; i < arr.length; i++) {

6:            arr[i] = lower++;

7:         }

8:         return arr;

9:      }

10:

11:      public static void main (String arg[]) {

12:         int theArray[];

13:         RangeClass theRange = new RangeClass();

14:

15:         theArray = theRange.makeRange(1,10);

16:         System.out.print("The array: [ ");

17:         for (int i = 0; i < theArray.length; i++) {

18:            System.out.print(theArray[i] + " ");

19:         }

20:         System.out.println("]");

21:      }

22:

23:   }


Die Ausgabe dieses Programms sieht so aus:

The array: [ 1 2 3 4 5 6 7 8 9 10 ]

Die Methode main()in dieser Klasse testet die Methode makeRange() durch Anlegen eines Bereichs, wobei die obere und untere Grenze des Bereichs 1 bzw. 10 ist (siehe Zeile 6). Dann wird eine for-Schleife benutzt, um die Werte des neuen Arrays auszugeben.

Das this-Schlüsselwort

Sicherlich möchten Sie im Körper einer Methodendefinition einmal auf das aktuelle Objekt verweisen, beispielsweise, um auf Instanzvariablen des Objekts zu zeigen oder das aktuelle Objekt als Argument an eine andere Methode weiterzugeben. Um auf das aktuelle Objekt Bezug zu nehmen, können Sie das Schlüsselwort this verwenden. Sie können es an jeder beliebigen Stelle eingeben, an der das Objekt erscheinen kann, z. B. in einer Punkt-Notation, um auf Instanzvariablen des Objekts zu verweisen, oder als Argument für eine Methode, als Ausgabewert der aktuellen Methode usw. Hier ein Beispiel:

t = this.x   ;   // Instanzvariable x für dieses Objekt

this.myMethod(this);   // Aufruf der in dieser Klasse definierten mymethod-Methode,

            // und Weitergabe an das aktuelle Objekt

return this;      // Ausgabe des aktuellen Objekts

In vielen Fällen können Sie eventuell das Schlüsselwort this weglassen. Sie können sich auf Instanzvariablen und Methodenaufrufe, die in der aktuellen Klasse definiert sind, einfach auch nach Name beziehen. this ist in diesen Referenzen implizit. Die ersten zwei Beispiele könnten somit auch wie folgt geschrieben werden:

t = x   ;      // Instanzvariable x für dieses Objekt

myMethod(this);      // Aufruf der in dieser Klasse definierten mymethod-Methode

Ob Sie das Schlüsselwort this für Instanzvariablen weglassen können, hängt davon ab, ob es Variablen mit dem gleichen Namen im lokalen Bereich gibt. Einzelheiten hierzu finden Sie im nächsten Abschnitt.

Da this eine Referenz auf die aktuelle Instanz einer Klasse ist, ist es sinnvoll, das Schlüsselwort nur innerhalb der Definition einer Instanzmethode zu verwenden. Klassenmethoden, d. h. Methoden, die mit dem Schlüsselwort static deklariert sind, können this nicht verwenden.

Variable Umfang- und Methodendefinitionen

Wenn Sie sich auf eine Variable in einer Methodendefinition beziehen, sucht Java zuerst eine Definition dieser Variablen im aktuellen Bereich (der ein Block sein kann), dann durchsucht es die äußeren Bereiche bis zur Definition der aktuellen Methode. Ist die gesuchte keine lokale Variable, sucht Java nach einer Definition dieser Variablen als Instanzvariable in der aktuellen Klasse und zum Schluß in jeder Superklasse.

Aufgrund der Art, in der Java nach dem Bereich einer bestimmten Variablen sucht, können Sie eine Variable in einem niedrigeren Bereich erstellen, so daß eine Definition der gleichen Variablen den Originalwert der Variablen »verbirgt«. Das kann aber zu Fehlern führen, die schwer zu finden sind.

Betrachten Sie z. B. dieses kleine Java-Programm:

class ScopeTest {

   int test = 10;

   void printTest () {

      int test = 20;

      System.out.println("test = " + test);

   }

}

Diese Klasse hat zwei Variablen mit dem gleichen Namen und der gleichen Definition: Die erste, eine Instanzvariable, hat den Namen test und ist auf den Wert 10 initialisiert. Die zweite ist eine lokale Variable mit dem gleichen Namen, jedoch dem Wert 20. Da die lokale Variable die Instanzvariable verbirgt, gibt die Methode println() für test den Wert 20 aus.

Sie können dies lösen, indem Sie this.test verwenden, um sich spezifisch auf die Instanzvariable zu beziehen, oder nur test, um sich auf die lokale Variable zu beziehen.

Eine heimtückischere Situation tritt ein, wenn Sie eine Variable in einer Subklasse, die bereits in einer Superklasse vorkommt, neu definieren. Das kann sehr komplizierte Fehler im Code verursachen. Beispielsweise werden Methoden aufgerufen, die den Wert einer Instanzvariablen ändern sollen, nun jedoch die falsche ändern. Ein anderer Fehler kann auftreten, wenn ein Objekt von einer Klasse in eine andere konvertiert wird. Eventuell wird dabei der Wert einer Instanzvariablen auf geheimnisvolle Weise geändert (da sie den Wert von der Superklasse, nicht von der beabsichtigten Klasse entnommen hat). Die beste Art, dieses Verhalten zu vermeiden, ist sicherzustellen, daß Sie beim Definieren von Variablen in einer Subklasse die Variablen in allen Superklassen dieser Klasse kennen und nichts duplizieren, was sich bereits dort befindet.

Argumente an Methoden abgeben

Wenn Sie eine Methode mit Objektparametern aufrufen, werden die Variablen, die Sie an den Körper der Methode abgeben, nach Referenz weitergereicht. Das bedeutet, daß sich alles, was Sie mit diesen Objekten in der Methode anstellen, gleichermaßen auf die Originalobjekte auswirkt. Dies beinhaltet Arrays und alle Objekte, die in Arrays enthalten sind. Wenn Sie ein Array an eine Methode weitergeben und dann seinen Inhalt ändern, wirkt sich das auch auf das Original-Array aus. (Beachten Sie, daß die Primitivtypen nach Wert weitergegeben werden.)

Wie das funktioniert, wird am folgenden Beispiel deutlich. Wir beginnen mit einer einfachen Klassendefinition, die nur eine Methode namens OneToZero() enthält (siehe Listing 6.3).

Listing 6.3: Die PassByReference-Klasse

1:   class PassByReference {

2:      int OneToZero (int arg[]) {

3:         int count = 0;

4:

5:         for (int i = 0; i < arg.length; i++) {

6:            if (arg[i] == 1) {

7:            count++;

8:            arg[i] = 0;

9:            }

10:         }

11:         return count;

12:      }

13:   }

Die Methode OneToZero() bewirkt zwei Dinge:

Listing 6.4 zeigt die Methode main() der Klasse PassByReference, die die Methode OneToZero() prüft:

Listing 6.4: Die Methode main() in PassByReference

1:   public static void main (String arg[]) {

2:      int arr[] = { 1, 3, 4, 5, 1, 1, 7 };

3:      PassByReference test = new PassByReference();

4:      int numOnes;

5:

6:      System.out.print("Values of the array: [ ");

7:      for (int i = 0; i < arr.length; i++) {

8:         System.out.print(arr[i] + " ");

9:      }

10:      System.out.println("]");

11:

12:      numOnes = test.OneToZero(arr);

13:      System.out.println("Number of Ones = " + numOnes);

14:      System.out.print("New values of the array: [ ");

15:      for (int i = 0; i < arr.length; i++) {

16:         System.out.print(arr[i] + " ");

17:      }

18:      System.out.println("]");

19:   }


Und hier die Ausgabe dieses Programms:

Values of the array: [ 1 3 4 5 1 1 7 ]

Number of Ones = 3

New values of the array: [ 0 3 4 5 0 0 7 ]

Wir gehen die Methode main() jetzt Zeile für Zeile durch, um zu sehen, was da passiert.

Klassenmethoden

Ebenso wie es Klassen- und Instanzvariablen gibt, gibt es in Java auch Klassen- und Instanzmethoden. Der Unterschied zwischen den zwei Arten von Methoden ist analog. Klassenmethoden sind global, betreffen also die gesamte Klasse, und sind für andere Klassen oder Objekte verfügbar. Deshalb können Klassenmethoden an beliebigen Stellen benutzt werden, ungeachtet dessen, ob eine Instanz der betreffenden Klasse vorhanden ist.

In der Java-Klassenbibliothek befindet sich z. B. die Klasse Math. Diese Klasse definiert zahlreiche mathematische Operationen, die in jedem Programm mit verschiedenen Zahlentypen benutzt werden können:

float root = Math.sqrt(453.0);


System.out.print("The larger of x und y is" + Math.max(x,y));

Um Klassenmethoden zu definieren, benutzen Sie das Schlüsselwort static vor der Methodendefinition, wie beim Erstellen von Klassenvariablen. Die Klassenmethode max könnte beispielsweise folgende Unterschrift haben:

static int max (int arg1, int arg2) { ... }

Auf ähnliche Weise liefert Java sogenannte Wrapper-Klassen für alle Grundtypen, z. B. Klassen für Integer, Float und Boolean. Anhand der in diesen Klassen definierten Klassenmethoden können Sie Objekte in Grundtypen und umgekehrt konvertieren. Die Klassenmethode parseInt() in der Klasse Integer gibt z. B. anhand einer Zeichenkette und einer Wurzel (Radix) den Wert dieser Zeichenkette als Ganzzahl aus:

int count = Integer.parseInt("42", 10) // Ergibt 42

Die meisten Methoden, die auf ein bestimmtes Objekt anwendbar sind oder sich auf ein Objekt auswirken, sollten als Instanzmethoden definiert werden. Methoden, die eine gewisse allgemeine Nützlichkeit bieten und sich nicht direkt auf eine Instanz einer Klasse auswirken, werden bevorzugt als Klassenmethoden deklariert.

Entwickeln von Java-Anwendungen

Sie haben gelernt, Klassen, Objekte, Klassen- und Instanzvariablen sowie Methoden zu erstellen. Alles, was Sie noch lernen müssen, um etwas Lauffähiges zu produzieren, ist das Schreiben einer Java-Anwendung.

Anwendungen, um Ihr Gedächtnis aufzufrischen, sind Java-Programme, die eigenständig laufen. Anwendungen unterscheiden sich von Applets, für die HotJava oder ein javafähiger Browser benötigt wird, um sie anzeigen zu können. Ein Großteil dessen, was Sie in den bisherigen Lektionen durchgearbeitet haben, sind Java-Anwendungen. Nächste Woche tauchen Sie in die Entwicklung von Applets ein. (Um Applets schreiben zu können, ist mehr Basiswissen erforderlich, denn Applets müssen auch mit dem Browser interagieren und das Grafiksystem zeichnen und aktualisieren. Das alles lernen Sie nächste Woche.)

Eine Java-Anwendung besteht aus einer oder mehreren Klassen und kann beliebig umfangreich sein. HotJava ist ein Beispiel einer Java-Anwendung. Das einzige, was Sie brauchen, um eine Java-Anwendung auszuführen, ist eine Klasse, die als »Sprungbrett« für den Rest Ihres Java-Programms dient. Ist Ihr Programm eher klein, kann eine Klasse unter Umständen genügen.

Die Klasse, die das Sprungbrett für Ihr Java-Programm bildet, muß eine main()-Methode haben. Wenn Sie Ihre kompilierte Java-Klasse (mit dem Java-Interpreter) ausführen, ist die Methode main() das erste, was aufgerufen wird. Das dürfte für Sie keine Überraschung mehr sein, da Sie ja in den bisherigen Lektionen mehrmals Java-Anwendungen mit main() erstellt haben.

Die Unterschrift der Methode main() sieht immer so aus:

public static void main (String arg[]) { ... }

Die einzelnen Teile von main() haben folgende Bedeutung:

In den Körper der main()-Methode kann jeder beliebige Code eingefügt werden, der benötigt wird, um eine Anwendung zu starten: Anfangsvariablen oder Instanzen von Klassen, die Sie deklariert haben.

Bei der Ausführung der main()-Methode bleibt zu berücksichtigen, daß es sich um eine Klassenmethode handelt. Deshalb wird die Klasse, die sie beinhaltet, nicht automatisch beim Ablauf des Programms ausgeführt. Soll diese Klasse als Objekt behandelt werden, müssen Sie sie direkt in die main()-Methode einbeziehen (bei allen bisherigen Beispielen ist das der Fall).

Java-Anwendungen und Befehlszeilenargumente

Da Java-Anwendungen in sich geschlossene Programme sind, sollte man in der Lage sein, Argumente oder Optionen an dieses Programm weiterzugeben, um zu ermitteln, wie das Programm abläuft oder um ein allgemeines Programm mit verschiedenen Eingabearten zu betreiben. Befehlszeilenargumente können für viele verschiedene Zwecke benutzt werden, z. B. um die Debugging-Eingabe zu aktivieren, den Namen einer Datei zu bezeichnen, die gelesen oder beschrieben werden soll, oder für andere Informationen, die Ihr Java-Programm wissen soll.

Argumente an Java-Programme abgeben

Um Argumente an ein Java-Programm weiterzugeben, hängen Sie sie lediglich an die Befehlszeile an, wenn Sie das Java-Programm ausführen:

java Myprogram argumentOne 2 three

In dieser Befehlszeile stehen drei Argumente: argumentOne, die Zahl 2 und das Wort three. Beachten Sie, daß die Argumente durch je ein Leerzeichen getrennt sind. Diese Befehlszeile erzeugt drei Argumente:

java Myprogram Java is cool

Um Argumente zu gruppieren, setzen Sie sie zwischen doppelte Anführungszeichen. Die nächste Befehlszeile produziert ein Argument:

java Myprogram "Java is cool"

Die doppelten Anführungszeichen werden wieder abgeschüttelt, bevor das Argument Ihr Java-Programm erreicht.

Handhaben von Argumenten in einem Java-Programm

Wie handhabt Java Argumente? Java speichert sie in einem Zeichenketten-Array, das an die Methode main() in Ihrem Java-Programm weitergegeben wird. Sie erinnern sich an die Unterschrift von main():

public static void main (String arg[]) { ... }

Hier ist arg der Name des Zeichenketten-Arrays, das die Argumentenliste enthält. Sie können sie nach Geschmack benennen. argv ist üblich (nach dem Array gleichen Namens in C und Unix).

Innerhalb Ihrer main()-Methode können Sie dann die Argumente, die Ihr Programm durch Wiederholung des Arrays von Argumenten erhalten hat, beliebig handhaben. Das Beispiel in Listing 6.5 ist eine sehr einfache Klasse, die die erhaltenen Argumente zeilenweise ausgibt.

Listing 6.5: Die EchoArgs-Klasse

1:   class EchoArgs {

2:      public static void main(String args[]) {

3:         for (int i = 0; i < args.length; i++) {

4:            System.out.println("Argument " + i + ": " + args[i]);

5:         }

6:      }

7:   }

Nachfolgend Ein- und Ausgabemuster aus diesem Programm:

java EchoArgs 1 2 3 jump
Argument 0: 1

Argument 1: 2

Argument 2: 3

Argument 3: jump

java Echo Args "foo bar" zap twaddle 5
Argument 0: foo bar

Argument 1: zap

Argument 2: twaddle

Argument 3: 5

Beachten Sie die Gruppierung der Argumente im Listing. Durch Anführungszeichen um foo bar wird veranlaßt, daß das Argument als eine Einheit innerhalb des Argumenten-Arrays behandelt wird.

Das Array von Argumenten ist in Java nicht mit argv in C und Unix identisch. Insbesondere arg[0], das erste Element im Argumenten-Array, ist das erste Argument in der Befehlszeile nach dem Namen der Klasse, nicht dem Namen des Programms wie in C. Achten Sie darauf ganz besonders beim Schreiben von Java-Programmen.

Ein wichtiger Faktor über die Argumente, die Sie an ein Java-Programm weitergeben, ist, daß diese Argumente in einem Zeichenketten-Array gespeichert werden. Das bedeutet, daß Argumente, die Sie an Ihr Java-Programm übergeben, in Zeichenketten konvertiert werden, damit sie im Argumenten-Array gespeichert werden können. Sollen sie nicht als Zeichenketten behandelt werden, müssen Sie sie in den gewünschten Typ umwandeln.

Nehmen wir beispielsweise an, Sie haben ein sehr einfaches Java-Programm namens SumAverage, das eine beliebige Zahl an numerischen Argumenten hernimmt und die Summe sowie den Mittelwert dieser Argumente ausgibt. Eine erste Möglichkeit der Weitergabe an dieses Programm ist in Listing 6.6 aufgeführt.

Listing 6.6: Erster Versuch mit der SumAverage-Klasse

1:   class SumAverage {

2:      public static void main (String args[]) {

3:         int sum = 0;

4:

5:         for (int i = 0; i < args.length; i++) {

6:            sum += args[i];

7:         }

8:

9:         System.out.println("Sum is: " + sum);

10:         System.out.println("Average is: " +

11:            (float)sum / (float)args.length);

12:      }

13:   }

Auf den ersten Blick sieht dieses Programm ganz einfach und übersichtlich aus. Eine for-Schleife wird auf das Argumenten-Array wiederholt ausgeführt, dann wird die Summe und der Mittelwert ermittelt und als letzter Schritt ausgegeben.

Was passiert aber, wenn Sie versuchen, dieses Programm zu kompilieren? Sie erhalten folgenden Fehler:

SumAverage.java:9: Incompatible type for +=. Can't convert java.lang.String to int.

   sum += args[i];

Diese Fehlermeldung erscheint, weil das Argumenten-Array ein Zeichenketten-Array ist. Obwohl Ganzzahlen an das Programm in der Befehlszeile weitergereicht wurden, werden diese Ganzzahlen in Zeichenketten konvertiert und dann im Array gespeichert. Um diese Ganzzahlen summieren zu können, müssen sie von Zeichenketten zurück in Ganzzahlen konvertiert werden. Für die Klasse Integer gibt es die Klassenmethode parseInt, die genau diesem Zweck dient. Wenn Sie Zeile 7 auf diese Methode abändern, funktioniert das Programm:

sum += Integer.parseInt(args[i]);

Wenn Sie jetzt das Programm kompilieren, läuft es fehlerfrei ab und gibt die erwarteten Ergebnisse aus. java SumAverage 1 2 3 ergibt beispielsweise folgende Ausgabe:

Sum is: 6

Average is: 2

Zusammenfassung

Heute haben Sie alle Teilchen, die Sie in den bisherigen Lektionen dieser Woche gelernt haben, vervollständigt, um Java-Klassen zu erstellen und sie in Java-Anwendungen zu benutzen. Im einzelnen haben Sie in dieser Lektion folgendes gelernt:


Fragen und Antworten

F: Ich habe versucht, eine konstante Variable in einer Methode zu erstellen, habe aber einen Kompilierfehler erhalten. Was mache ich falsch?

A: Konstanten können nur aus Klassen- oder Instanzvariablen (final) erstellt werden. Lokale Variablen können nicht konstant sein.

F: Die Begriffe static und final drücken nicht gerade aus, daß Sie zum Erstellen von Klassenvariablen, Klassenmethoden und Konstanten verwendet werden. Warum benutzt man nicht Begriffe wie class und const?

A: static stammt aus Javas Erbschaft von C++. C++ nutzt das Schlüsselwort static, um Speicher für Klassenvariablen und Methoden zu reservieren (die in C++ auch nicht Klassenmethoden und Variablen genannt werden).

final ist ein neuer Begriff. Er wird allgemein für Klassen und Methoden benutzt, um anzuzeigen, daß diese Dinge nicht für Subklassen oder zum Overriding benutzt werden können. Das Schlüsselwort final für Variablen ist bei diesem Verhalten konsistent. final-Variablen sind nicht ganz mit Konstantenvariablen in C++ identisch, deshalb wird nicht das Schlüsselwort const benutzt.

F: Eine meiner Klassen hat eine Instanzvariable namens name. Ferner habe ich eine lokale Variable namens name in einer Methode, die aufgrund des variablen Bereichs von der lokalen Variablen verborgen wird. Gibt es eine Möglichkeit, den Wert der Instanzvariablen zu erhalten?

A: Die einfachste Möglichkeit ist, die lokale Variable nicht genauso zu benennen wie die Instanzvariable. Falls Sie unbedingt den gleichen Namen verwenden wollen, können Sie this.name verwenden, um spezifisch auf die Instanzvariable zu verweisen, während Sie als Referenz auf die lokale Variable name verwenden.

F: Wie kann ich Befehlszeilenargumente an ein Applet weitergeben?

A: Haben Sie bereits ein Applet geschrieben? Haben Sie sich etwa in diesem Buch schon weiter vorgearbeitet? Die Antwort ist, daß Sie HTML-Attribute benutzen, um dies zu erreichen, also nicht die Befehlszeile (bei Applets haben Sie keine Befehlszeile). Sie lernen hierüber noch in dieser Woche.

F : Ich habe ein Programm für vier Argumente geschrieben, wenn ich aber weniger Argumente angebe, stürzt das Programm ab und ich erhalte einen Laufzeitfehler.

A : Prüfen Sie Zahl und Typ der Argumente, die Ihr Programm erwartet. Java überprüft das nicht automatisch für Sie. Verlangt Ihr Programm vier Argumente, müssen es tatsächlich vier sein, ansonsten erhalten Sie eine Fehlermeldung.


Copyright ©1996 Markt&Technik
Buch- und Software- Verlag GmbH
Alle Rechte vorbehalten. All rights reserved.

Schreiben Sie uns!

Previous Page TOC Index Next Page See Page