Dieser Teil führt in das Programmieren mit Java ein. Voraussetzung

Werbung
Java
Dieser Teil führt in das Programmieren mit Java ein. Voraussetzung sind gute C++ Kenntnisse.
Es wird gezeigt, wie Java-Programme entwickelt werden und der Unterschied zur C++ wird diskutiert.
Am Schluss werden einige charakteristische Java Beispiel-Programme gezeigt.
Inhalt
1.
Java-Technologie...................................................................................................... 5
1.1. Java-Kode ........................................................................................................... 5
1.2. Java-Plattform ..................................................................................................... 7
2.
Programmentwicklung mit Java .................................................................................10
2.1. Anwendungen .....................................................................................................11
2.1.1.
Übersetzen von Programmen ..........................................................................12
2.1.2.
Anwendungen starten ....................................................................................13
2.1.3.
Kommentare ................................................................................................13
2.1.4.
Klassendefinition ...........................................................................................13
Arbeiten mit Java
Prof.Dr. Alois Schütte
1/65
2.1.5.
Die Methode main .........................................................................................14
2.1.6.
Verwendung von Klassen und Objekten............................................................17
2.2. Applets ..............................................................................................................17
3.
2.2.1.
Import von Klassen und Packages ...................................................................18
2.2.2.
Definition einer von Applet abgeleiteten Klasse..................................................21
2.2.3.
Implementierung von Applet Methoden ............................................................21
2.2.4.
Applet ausführen...........................................................................................22
Unterschied Java und C++ .......................................................................................24
3.1. Variablen ...........................................................................................................24
3.2. Unterschied Wert <--> Referenz ...........................................................................25
3.2.1.
Objekte kopieren ..........................................................................................26
3.2.2.
Zeiger .........................................................................................................27
3.3. Arrays ...............................................................................................................27
3.3.1.
Anlegen von Arrays .......................................................................................28
3.4. Operatoren.........................................................................................................31
3.5. Typkonvertierung ................................................................................................33
Arbeiten mit Java
Prof.Dr. Alois Schütte
2/65
3.5.1.
Numerische Konvertierungen ..........................................................................33
3.6. Anweisungen (if/else, while und do/while) ..............................................................34
3.7. Garbage Collection ..............................................................................................34
3.8. import-Anweisung ...............................................................................................35
3.9. Subklassen und Vererbung ...................................................................................37
4.
3.9.1.
Modifier für Klassen .......................................................................................38
3.9.2.
Modifier für Methoden ....................................................................................38
3.9.3.
Modifikatoren ...............................................................................................39
3.9.4.
Superklassen, Objekte und Klassenhierarchie....................................................39
3.9.5.
Subklassen-Konstruktoren..............................................................................39
3.9.6.
Abstrakte Klasssen und Schnittstellen ..............................................................41
3.9.7.
Schnittstellen ...............................................................................................41
3.9.8.
Schnittstellen erweitern .................................................................................42
Java Beispiele .........................................................................................................43
4.1. I/O ....................................................................................................................43
4.1.1.
Arbeiten mit Java
Übersicht über Streams .................................................................................46
Prof.Dr. Alois Schütte
3/65
4.2. File Streams .......................................................................................................50
4.3. Filter Streams .....................................................................................................53
4.4. Interfaces ..........................................................................................................60
4.4.1.
Definition eines Interface ...............................................................................63
4.4.2.
Implementierung eines Interface.....................................................................64
Arbeiten mit Java
Prof.Dr. Alois Schütte
4/65
1.
Java-Technologie
Java-Technologie1 ist der Sammelbegriff für
ƒ die Programmiersprache Java,
ƒ die Java APIs und
ƒ die Java Plattform.
1.1. Java-Kode
Java ist eine Hochsprache, die durch folgende Begriffe charakterisiert werden kann:
ƒ objektorientiert
ƒ robust
ƒ sicher
ƒ architekturneutral
ƒ portabel
ƒ performant
1
Die Ausarbeitung basiert auf Online Veröffentlichungen von Sun.
Arbeiten mit Java
Prof.Dr. Alois Schütte
5/65
Java Quellprogramme müssen zunächst übersetzt werden. Dadurch entsteht ein Zwischenkode
(Java Bytecode). Dieser plattformunabhängige Kode wird dann in einer Ablaufumgebung vom
Bytekode Interpreter der Zielumgebung ausgeführt.
Der Bytekode ist „Maschinenkode der Java Virtual Machine“ (Java VM).
Durch diesen plattformunabhängigen Bytekode und der Verfügbarkeit der Java VM auf nahezu
allen Plattformen (Handy, PC bis zu Mainframe) sind portable Anwendungen realisierbar:
Arbeiten mit Java
Prof.Dr. Alois Schütte
6/65
1.2. Java-Plattform
Eine Plattform ist eine Hardware/Software Umgebung, in der Programme ablaufen können. Die
Java Plattform ist eine reine Software Umgebung, die auf einer Hardwareplattform aufsetzt.
Die Java Plattform besteht aus:
ƒ der Java Virtual Machine (Java VM) und
ƒ dem Java Application Programming Interface (Java API).
Das folgende Bild zeigt die Java Plattform:
Arbeiten mit Java
Prof.Dr. Alois Schütte
7/65
Java wird nicht nur verwendet, um Applets zu realisieren, sondern auch um ServerAnwendungen zu realisieren. Eine Anwendung (im Gegensatz zum Applet) ist ein eigenständiges
Programm, das auf der Java-Plattform abläuft.
Um sowohl Applets als auch Java Anwendungen realisieren zu können, sind APIs für unterschiedliche Bereiche verfügbar, wie etwa Netzwerkkommunikation, Benutzerschnittstellen, Sicherheit
u.v.m.
Die folgende Abbildung zeigt die wesentlichen Bestandteile des Java Software Development Kits
(SDK).
Arbeiten mit Java
Prof.Dr. Alois Schütte
8/65
Arbeiten mit Java
Prof.Dr. Alois Schütte
9/65
2.
Programmentwicklung mit Java
Zunächst betrachten wir die Entwicklung einer Anwendung, dann wird gezeigt, wie Applets programmiert werden können.
Die Entwicklung wird gezeigt an der „klassischen“ Hello World Anwendung.
Anwendung:
Arbeiten mit Java
Prof.Dr. Alois Schütte
10/65
Applet im Browser:
2.1. Anwendungen
Am Beispiel eines HelloWorld Programms wird die Entwicklung einer Java Anwendun
zeigt.
Arbeiten mit Java
Prof.Dr. Alois Schütte
g ge-
11/65
$ cat helloWorld.java
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
$
2.1.1. Übersetzen von Programmen
Das Java-Programm wird mit dem Java-Compiler javac übersetzt:
$ ls -l
-rw------1 as
$ javac helloWorld.java
$ ls -l
-rw------1 as
-rw------1 as
$
users
269 Mär 14 13:51 helloWorld.java
users
users
429 Mär 14 13:54 helloWorld.class
269 Mär 14 13:51 helloWorld.java
Es entsteht eine Datei mit Namen helloWorld.class. helloWorld ist der Name der Klasse in der
Quelldatei, .class zeigt, dass es sich um Bytekote handelt.
Arbeiten mit Java
Prof.Dr. Alois Schütte
12/65
2.1.2. Anwendungen starten
Durch den Java-Interpreter java kann die Anwendung gestartet werden. Das Argument von java
ist die Klasse, die „Startmethode“ main enthält.
$ java helloWorld
Hello World!
$
2.1.3. Kommentare
In Java sind Kommentare in C++ Art möglich:
$ cat helloWorld.java
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
$
2.1.4. Klassendefinition
In Java ist jede Methode (Funktion) und jede Variable Bestandteil einer Klasse oder eines Objektes (Exemplar einer Klasse). Globale Funktionen oder Variablen sind nicht erlaubt.
Arbeiten mit Java
Prof.Dr. Alois Schütte
13/65
Die Klassendefinition in der einfachsten form ist
class name { …}
$ cat helloWorld.java
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
$
Eine Klassedefinition beschreibt Daten und das Verhalten von Objekt-Exemplaren der Klasse. Wenn eine Klasse instanziiert wird, wird ein Objekt erzeugt, dass sich so verhält, wie es die
Klassendefinition vorsieht.
Daten der Klasse werden in Variablen abgelegt, das Verhalten wird durch Methoden beschrieben.
Die Klasse helloWorld hat keine Daten. Sie besitzt eine Methode mit Namen main.
2.1.5. Die Methode main
Der Ausgangspunkt für Java Anwendungen ist die Methode main. Der Java-Interpreter startet als
erstes die Methode main, von wo aus dann alle anderen Aktivitäten gestartet werden.
Arbeiten mit Java
Prof.Dr. Alois Schütte
14/65
$ cat helloWorld.java
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
$
Die Methode main hat folgendes Aussehen:
public static void main(String[] args)
Die Methodensignatur enthält drei Modifikatoren:
ƒ public
definiert, dass main von allen Objekten aufrufbar ist.
ƒ static
definiert main als Klassenmethode
ƒ void
besagt, dass main keinen Rückgabewert hat.
Arbeiten mit Java
Prof.Dr. Alois Schütte
15/65
Die Argumente von main, also die Kommandozeilen-Parmeter werden in einem Array von Strings
abgelegt. Das Beispielprogramm hat keine Parameter.
Achtung (Unterschied zu C++)
args ist ein Array von Strings, wobei der Programmname nicht enthalten ist.
Die Verwendung von Kommandozeilenargumenten zeigt folgendes Beispiel (echo):
$ cat echo.java
public class echo {
public static void main (String[] args) {
for (int i = 0; i < args.length; i++)
System.out.print(args[i] + " ");
System.out.println();
}
}
$
Wenn numerische Kommandozeilenargumente verwendet werden sollen, so ist der String zu
konvertieren, etwa durch:
int firstArg;
if (args.length > 0)
firstArg = Integer.parseInt(args[0]);
Arbeiten mit Java
Prof.Dr. Alois Schütte
16/65
2.1.6.
Verwendung von Klassen und Objekten
Das HelloWorld-Programm ist ein einfaches Programm, es enthält keine weiteren Klassendefinitionen.
Das Programm verwendet eine Klasse System, die zu einem API der Java-Plattform gehört.
$ cat helloWorld.java
/**
* The HelloWorldApp class implements an application that
* simply displays "Hello World!" to the standard output.
*/
class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}
$
System.out ist der volle Name der Variablen out der Klasse System. Wenn die Klasse System geladen wird, so wird ein PrintStream-Objekt erzeugt und der Variablen out zugewiesen. Dadurch
kann die Methode println dieses Objektes aufgerufen werden.
2.2. Applets
Applets werden von einem Browser aus aufgerufen.
Der Java-Kode für das Hello World Applet ist ebenfalls einfach:
Arbeiten mit Java
Prof.Dr. Alois Schütte
17/65
$ cat helloWorldApplet.java
import java.applet.Applet;
import java.awt.Graphics;
/**
* The helloWorldApplet class implements an applet that
* simply displays "Hello World!".
*/
public class helloWorldApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
$
2.2.1. Import von Klassen und Packages
$ cat helloWorldApplet.java
import java.applet.Applet;
import java.awt.Graphics;
/**
* The helloWorldApplet class implements an applet that
* simply displays "Hello World!".
*/
public class helloWorldApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
Arbeiten mit Java
Prof.Dr. Alois Schütte
18/65
$
Die beiden ersten Zeilen importieren die Klassen Applet und Graphics. Ohne die beiden Zeilen
würde das Applet auch funktionieren, wenn man den Kode wie folgt erweitert:
public class helloWorldApplet extends java.applet.Applet {
public void paint(java.awt.Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
Durch das Importieren kann man also Klassen ohne vollen Namen angeben zu müssen verwenden.
Das Package java.applet beinhaltet die speziell für Applets erforderlichen Klassen; java.awt
(abstract window toolkit) ist eine Sammlung von Klassen zu Realisierung von graphischen Benutzerschnittstellen.
Wenn das gesamte Package importiert werden soll, also nicht nur eine Klasse, so kann man den
Platzhalter „*“ verwenden:
Arbeiten mit Java
Prof.Dr. Alois Schütte
19/65
$ cat helloWorldApplet.java
import java.applet.*;
import java.awt.*;
/**
* The helloWorldApplet class implements an applet that
* simply displays "Hello World!".
*/
public class helloWorldApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
$
Jede Klasse in Java ist Bestandteil eines Package. Ein Package ist eine Menge von Klassen und
Interfaces, wodurch Zugriffsschutz und Namensräume geregelt werden.
Wenn ein Programm nicht explizit eine package-Anweisung am Anfang enthält, so gehört die
Klasse zum Default Package (so wie in unserem Hello World Beispiel).
Arbeiten mit Java
Prof.Dr. Alois Schütte
20/65
2.2.2. Definition einer von Applet abgeleiteten Klasse
$ cat helloWorldApplet.java
import java.applet.*;
import java.awt.*;
/**
* The helloWorldApplet class implements an applet that
* simply displays "Hello World!".
*/
public class helloWorldApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
$
Jedes Applet muss eine Klasse enthalten, die von der Klasse Applet abgeleitet ist. Dadurch erben
sie die Eigenschaften, die zur Kommunikation mit Browsern erforderlich sind.
Durch das Schlüsselwort extends wird ausgedrückt, dass die Klasse helloWorldApplet von der
Klasse Applet abgeleitet ist.
Wenn ein Browser ein Applet lädt, wird die Klasse initialisiert, die von Applet abgeleitet wurde.
2.2.3.
Implementierung von Applet Methoden
Jedes Applet muss mindestens eine der Methoden init, start oder paint beinhalten.
Arbeiten mit Java
Prof.Dr. Alois Schütte
21/65
$ cat helloWorldApplet.java
import java.applet.*;
import java.awt.*;
/**
* The helloWorldApplet class implements an applet that
* simply displays "Hello World!".
*/
public class helloWorldApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello world!", 50, 25); // Display "Hello world!"
}
}
$
Die Methode paint wird redefiniert: der formale Parameter ist ein Graphics Objekt. Bei Ausführung des Applet wird der Applet Konntext als aktueller Parameter übergeben; damit kann dann
die Metode drawString des Graphics Objekts „Hello world“ ausgeben an die Position 50, 25.
2.2.4.
Applet ausführen
Ein Applet wird in ein HTML Dokument einebettet durch das Tag „APPLET“.
Arbeiten mit Java
Prof.Dr. Alois Schütte
22/65
$ cat helloWorld.html
<HTML>
<HEAD>
<TITLE>The Hello World Applet</TITLE>
</HEAD>
<BODY>
Hello World Applet: <br>
<APPLET CODE="helloWorldApplet.class" WIDTH=150 HEIGHT=25>
</APPLET>
</BODY>
</HTML>
$
Durch die Attribute WIDTH und HEIGHT wird der Applet Kontext für die Methode paint bestimmt.
Arbeiten mit Java
Prof.Dr. Alois Schütte
23/65
3.
Unterschied Java und C++
Im Folgenden wird Java erklärt, in dem der Unterschied zu C++ beschrieben wird.
3.1. Variablen
Instanzvariablen werden initialisiert, wenn ein Objekt erzeugt wird. Für eine komplexere
Initialisierung als mit den einfachen Variablenstartwerten gibt es Konstruktor-Methoden, die
ausgeführt werden, wenn eine neue Instanz der Klasse erzeugt wird.
Klassenvariablen werden initialisiert, wenn die Klasse das erste Mal geladen wird. Man
kann Initialisierungsmethoden für Klassenvariablen schreiben (sog. statische Initialisierer), die
benötigt werden für Klassen, die native-Methoden implementieren.
Beispiel:
class A {
static int Kvar;
int Ivar;
// Klassenvariable
// Instanzvariable
}
Als Anfangswerte für die Initialisierung wird verwendet:
Typ
Boolean
Char
Arbeiten mit Java
Prof.Dr. Alois Schütte
Anfangswert
false
'\u000'
24/65
Ganzzahl (int, byte, short, long) 0
+0.0
Gleitkomma
null
andere Referenzen
3.2. Unterschied Wert <--> Referenz
Als einfache Datentypen werden die vordefinierten Datentypen (int, float, …) bezeichnet. Objekte und Arrays werden als nicht-einfache Datentypen bezeichnet bzw. als Referenzdatentypen.
In Java gilt:
ƒ einfache Typen werden immer durch den Wert übergeben
ƒ Arrays und Objekte werden immer durch Referenz übergeben
Die Änderung einer Referenz innerhalb einer Funktion hat keine Wirkung nach "außen":
Beispiel:
Weil Objekte per Referenz übergeben werden, können 2 Variable dasselbe Objekt referenzieren:
Arbeiten mit Java
Prof.Dr. Alois Schütte
25/65
Button p, q;
p = new Button();
q = p;
p.setLabel("OK");
String s = q.getLabe();
// p referenziert ein Button Objekt
// q referenziert denselben Button
// eine Änderung im Objekt durch p ...
// ...ist auch durch q sichtbar, s ="OK"
Dies gilt nicht für einfache Typen:
int i = 3;
int j = i;
i = 2;
//
//
//
//
i enthält den Wert 3
j enthält eine Kopie des Wertes in i
eine Änderung von i bewirkt
keine Änderung von j; i == 2, j == 3
3.2.1. Objekte kopieren
Button a = new Button("Okay");
Button b = new Button("Cancel");
a = b;
Im o.a. Beispiel wird deutlich: die Variable a enthält eine Referenz auf das Objekt, welches von b
refereziert wird; das Objekt das a vor der Zuweisung (a=b) referenziert hat, ist verloren.
Um Daten von einem Objekt in ein anderes zu kopieren, benutzt man die Methode clone().
Die clone()-Methode erzeugt ein neues Objekt desselben Typs wie das Ursprungsobjekt und initialsiert die Datenfelder des neuen, „geklonten“ Objektes mit den aktuellen Werten der Datenfelder des Ursprungsobjektes:
Arbeiten mit Java
Prof.Dr. Alois Schütte
26/65
Vector b = new Vector;
c = b.clone();
D.h. die Variable c enthält ein Duplikat des von b referenzierten Objektes
3.2.2.
Zeiger
In Java gibt es keine Zeiger.
Referenzieren und Dereferenzieren von Objekten wird automatisch vorgenommen; es ist
nicht erlaubt, Speicheradressen zu manipulieren
Gründe für diese Designentscheidung sind:
ƒ Zeiger sind in C++ häufig eine Fehlerquelle
ƒ die Sprache wird ohne Zeiger vereinfacht
ƒ Zeiger und Zeigerarithmetik können dazu benutzt werden, Laufzeitüberprüfungen und Sicherheitsmechanismen zu umgehen (= Sicherheitsgarantie)
3.3. Arrays
Arrays in Java werden durch Referenzen manipuliert und dynamisch mit new erzeugt. Ein
Garbage Collector gibt den nicht mehr benötigten Speicher von Arrays frei, wenn sie nicht
mehr benötigt werden.
Arbeiten mit Java
Prof.Dr. Alois Schütte
27/65
3.3.1.
Anlegen von Arrays
Arrays können auf zwei Arten angelegt werden:
1. Möglichkeit: mit new.
Button buttons[] = new Button [10];
Dabei werden die Elemente des Arrays auf den Standardwert ihres Typs initialisiert, z.B
int_Array-Elemente auf 0 initialisiert; die Arrays von Objekten werden auf null initialisiert
2. Möglichkeit: dynamisches Anlegen eines Arrays und Initialisierung mit den angegebenen Werten.
int look_up table[] = [1,2,4,8,16];
Ein mehrdimensionales Array wird mit new angelegt, indem die entsprechende Anzahl von Elementen in [] für jede Dimension angegeben wird:
byte TwoDimArray[][] = new byte[256][16];
Bei allen Arrayreferenzen wird der Index überprüft. Liegt der Index außerhalb der Grenzen, so
wird eine „ArrayIndexOutOfBounds“ Exception erzeugt.
Die Größe eines Arrays ist nicht Teil seines Typs, d.h. es kann eine Variable deklariert werden,
die z. B. vom Typ String[] ist, und ihr ein Array aus String- Objekten zuweisen, egal wie lang
dieses Array ist:
Arbeiten mit Java
Prof.Dr. Alois Schütte
28/65
String[] strings;
strings = new String[10];
strings = new String[20];
// diese Variable weist auf ein String-Array
// das nur 10 Strings enthält
// oder 20
Das folgende Beispiel zeigt die Verwendung von Variablen und Arrays im Zusammenhang:
Arbeiten mit Java
Prof.Dr. Alois Schütte
29/65
$ cat tArray.java
class tArray {
public static void main(String[] args) {
int[][] iA = new int[4][3];
//2 dim. int Array
iA[1][1] = 6;
System.out.println("int array:");
for (int i=0; i<2; i++) {
for (int j=0; j<3; j++)
System.out.print(iA[i][j]+" ");
System.out.println();
}
float[][] fA = new float[4][]; //2 dim. Array mit variabler Anz. Spalten
for (int i=0; i<fA.length; i++) {
fA[i] = new float[i+1];
}
fA[1][1] = 6;
System.out.println("\nfloat array:");
for (int i=0; i<fA.length; i++) {
for (int j=0; j<fA[i].length; j++)
System.out.print(fA[i][j]+" ");
System.out.println();
}
}
}
Arbeiten mit Java
Prof.Dr. Alois Schütte
30/65
Die Ausgabe des letzten Programms:
$ java tArray
int array:
0 0 0
0 6 0
float array:
0.0
0.0 6.0
0.0 0.0 0.0
0.0 0.0 0.0 0.0
$
3.4. Operatoren
Bis auf die nachfolgenden Ausnahmen, existieren die Operatoren von C++.
Folgende Operatoren werden in Java nicht unterstützt:
• Kommaoperator
• * und &-Operatoren (Zeiger)
• sizeof-Operator
Zusätzlich gibt es folgende Operatoren:
Arbeiten mit Java
Prof.Dr. Alois Schütte
31/65
• +-Operator zum Konkatenieren von Strings:
wird auf String-Werte angewendet; ist nur ein Operand ein String, so wird der andere in einen String konvertiert; diese Umwandlung geschieht bei einfachen Datentypen automatisch
und bei nicht-einfachen Datentypen durch den Aufruf der Methode toString()
• instanceof (Objekt instanceof gesuchteKlasse):
prüft, ob Objekt eine Instanz der Klasse gesuchteKlasse ist. Das bedeutet, dass der linke
Operand ein Referenztyp sein muss. Der rechte Operand ist ein Typ- (bzw. Klassen-) Bezeichner.
instanceof liefert true, wenn das Objekt auf der linken Seite eine Instanz der Klasse ist, die
auf der rechten Seite angegeben ist
instanceof liefert false, wenn das Objekt auf der linken Seite den Wert null hat (nullReferenz ist keine Instanz irgendeines Objekttyps)
• >>>:
alle integralen Typen in Java sind vorzeichenbehaftet, dieser Operator behandelt den Wert,
der geshiftet werden soll, als nicht vorzeichenbehafteten Wert und schiebt die Bits mit einer
Nullerweiterung nach rechts
• & und |:
integrale Typen wie in C++
boolean: beide Operanden werden ausgewertet, auch wenn das Ergebnis schon feststeht
(nachdem der linke Operand ausgewertet ist)
• [] (Zugriff auf Felder) und . (Zugriff auf Einträge) werden in Java nicht als Operatoren gewertet
Arbeiten mit Java
Prof.Dr. Alois Schütte
32/65
In Java ist keine Operatorüberladung möglich.
3.5. Typkonvertierung
Folgende Regeln gelten zur Typkonvertierung:
• boolean kann in keinen anderen Typ konvertiert werden und kein Typ kann nach boolean
konvertiert werden.
• Alle numerischen Typen können in beliebig andere numerische Typen konvertiert werden.
• Ein Referenztyp kann in einen anderen Referenztyp konvertiert werden, wenn der Ausgangstyp vom Zieltyp abgeleitet wurde.
3.5.1.
Numerische Konvertierungen
Wenn eine Variable in einen anderen Typen konvertiert werden soll, so muss ihr der gewünschte
Typ in Klammern vorangestellt werden:
double x = 674.14;
int i = (int)x;
Bei Konvertierungen muss beachtet werden, dass mit der Konvertierung ein Verlust an Genauigkeit sowie eine Einschränkung des Wertebereiches einhergehen kann. Es gibt folgende Regeln:
• Bei der Konvertierung eines Gleitpunkttyps in einen Ganzzahltyp werden alle
Nachkommastellen abgeschnitten. Falls der Wert der Vorkommastellen zu groß bzw. zu klein
ist, um ihn durch den betreffenden Ganzzahltyp darzustellen, resultiert der größte bzw. der
kleinste mit dem Ganzzahltyp darstellbare Wert.
Arbeiten mit Java
Prof.Dr. Alois Schütte
33/65
• Bei der Konvertierung eines Ganzzahltyps in einen kleineren Ganzzahltyp werden die überzähligen Bits abgeschnitten. Das kann einen Wechsel des Vorzeichens bewirken.
• Ein Ganzzahltyp kann ohne eine explizite Konvertierung an einen größeren Ganzzahltyp zugewiesen werden. So können alle Ausdrücke vom Typ byte und short an eine Variable vom
Typ int zugewiesen werden.
• Der Typ char ist ohne explizite Konvertierung zuweisungskompatibel zu short, int und long.
• Bei einer Konvertierung aus dem Typ double in den Typ float resultiert derjenige float-Wert,
der gegenüber dem double-Wert die geringste Differenz aufweist.
3.6. Anweisungen (if/else, while und do/while)
Bis auf die folgenden Ausnahmen existieren die Kontrollstrukturen von C++.
In Bedingunden (von if, while) ist null und nicht gleich false und Werte ungleich 0 und nicht-null
Werte sind nicht das gleiche wie true.
Es gibt kein goto-Konstrukt.
3.7. Garbage Collection
In Java gibt es kein Gegenstück zum new-Operator, das ein Objekt wieder entfernt. Auch Destruktoren im Sinne von C++ gibt es nicht. An Stelle expliziter Freigabe von Objekten gibt es einen Mechanismus, der sich automatisch darum kümmert: der Garbage Collector.
Der Garbage Collector prüft, ob es noch Verweise auf ein Objekt gibt. Wird ein Objekt von niemand mehr referenziert, wird es automatisch freigegeben.
Java gibt keine Garantien, wann die Garbage Collection stattfindet oder in welcher Reihenfolge
die Objekte freigegeben werden.
Arbeiten mit Java
Prof.Dr. Alois Schütte
34/65
Garbage Collection gibt automatisch die Speicherressourcen von Objekten frei, aber Objekte
können noch andere Ressourcen besitzen, wie Dateideskriptoren oder Sockets. Der Garbage Collector kann solche Ressourcen nicht freigeben, deshalb muss man finalizer-Methoden schreiben,
die z.B. offene Dateien schließen, Netzwerkverbindungen beenden.
Wenn ein Objekt einen Finalizer hat, so wird diese Methode aufgerufen, bevor der Garbage Collector das Objekt löscht. Nach dem Aufruf des Finalizers werden die Objekte nicht sofort freigegeben. Der Grund ist, dass der Finalizer ein Objekt "wiederbeleben" kann, indem es den thisZeiger irgendwo speichert, so dass das Objekt wieder eine Referenz hat.
Beispiel:
/* schließt einen Stream, wenn der Garbage Collector seine Arbeit verrichtet;
überprüft jedoch zuerst, ob der Deskriptor nicht schon geschlossen ist */
protected void finalize() throws IOException
{
if (fd != null) close();
}
3.8. import-Anweisung
Die package-Anweisung dient dazu, eine Sammlung von Klassen zu einer Einheit zusammenzufassen. Um die Zugehörigkeit einer Quelldatei zu einem Package anzugeben, wird vor der Deklaration von Klassen eine Package-Anweisung in der Quelldatei eingefügt. Dem Schlüsselwort Package folgt der Package-Name.
Arbeiten mit Java
Prof.Dr. Alois Schütte
35/65
package tools;
Zum Importieren eines Packages oder einer Klasse aus einem Package definiert Java die importAnweisung. Diese Anweisung stellt Javaklassen für die aktuelle Klasse unter einem abgekürzten
Namen zur Verfügung.
import stellt weder die Klasse zur Verfügung , noch "liest" es sie tatsächlich ein, sondern es
spart nur Schreibarbeit und macht den Kode lesbarer.
Es ist eine beliebige Anzahl von import-Anweisungen möglich. Sie müssen aber nach der optionalen package Anweisung am Anfang der Datei stehen und vor der ersten Klassen oder Schnittstellendefinition in der Datei.
Es sind 3 Formen möglich:
1. Form: import package;
ermöglicht dem angegebenen Paket durch den Namen seiner letzten Komponente angegeben zu
werden
import java.awt.image
java.awt.image.ImageFilter kann als image.ImageFilter aufgerufen werden.
2. Form: import package.class;
ermöglicht es der angegebenen Klasse in dem angegebenen Paket nur durch den Klassennamen
benutzt zu werden
import java.util.Hashtable;
Arbeiten mit Java
Prof.Dr. Alois Schütte
36/65
nur Hashtable statt java.util.Hashtable
3. Form: import package.*;
alle Klassen des Paketes werden durch ihre Klassennamen verfügbar gemacht
import java.lang.*
ist implizit in jedem Javaprogramm enthalten
Werden 2 Pakete, die Klassen mit gleichen Namen haben, importiert, kommt es zu einer Fehlermeldung, wenn eine Klasse mit ihrem nicht mehr eindeutigen kurzen Namen benutzt wird.
3.9. Subklassen und Vererbung
Durch Vererbung können Klassen definiert werden, die auf einer anderen Klasse basieren. Diese
neuen Klassen stellen eine Erweiterung und Spezialisierung ihrer Basisklasse dar. Die Subklasse
kann neue Methoden und Elemente hinzufügen oder bestehende Methoden überschreiben. Wenn
von einer Klasse einen Subklasse abgeleitet wird, muss die Subklasse im Kopf ihrer Deklaration
das Schlüsselwort extends benutzen. Hinter extends muss genau eine Klasse angegeben werden.
public class A extends B
{
...
}
A ist eine Subklasse von B, d.h. A erbt alle Variablen und Methoden der Klasse B, außer die als
private gekennzeichneten.
Arbeiten mit Java
Prof.Dr. Alois Schütte
37/65
3.9.1. Modifier für Klassen
abstract:
Abstrakte Klassen dienen nur dazu, eine Klassenstruktur festzulegen, ohne Implementierungen
vorzunehmen. Eine abstrakte Klasse darf nicht instantiiert werden. Von ihr muss erst eine
Unterklasse abgeleitet werden, die die Methoden der abstrakten Klasse implementiert.
final:
Von Klassen, die mit final gekennzeichnet sind, können keine Unterklassen abgeleitet werden. Eine Klasse darf nicht gleichzeitg als abstract und final deklariert werden.
3.9.2. Modifier für Methoden
final:
Eine mit final gekennzeichnete Methode kann nicht überschrieben werden.
static:
Static-Methoden gelten implizit als final und können deshalb nicht überschrieben werden.
abstract:
Abstrakte Methoden sind dazu gedacht, die Aufrufstruktur, aber nicht aber die Implementierung festzulegen. Sie müssen in einer Subklasse implementiert werden, die nicht abstrakt ist.
Abstrakte Methoden dürfen nur in abstrakten Klassen deklariert werden.
Arbeiten mit Java
Prof.Dr. Alois Schütte
38/65
3.9.3.
Modifikatoren
Situation
public default protected
erreichbar für nicht-Subklasse aus dem gleichen
Paket?
erreichbar für Subklasse aus dem gleichen Paket?
erreichbar für nicht-Subklasse aus einem anderen
Paket?
erreichbar für Subklasse aus einem anderen Paket?
geerbt von Subklasse in gleichem Paket?
geerbt von Subklasse in einem anderen Paket?
3.9.4.
private
private
protected
ja
ja
ja
nein
nein
ja
ja
ja
nein
nein
ja
nein
nein
nein
nein
ja
nein
nein
nein
nein
ja
ja
ja
nein
ja
ja
ja
ja
nein
nein
Superklassen, Objekte und Klassenhierarchie
Jede Klasse, die definiert wird, besitzt eine Superklasse. Wenn die Superklasse nicht in der extends-Klausel angegeben ist, so ist die Superklasse implizit Object. Object ist die einzige Klasse,
die keine Superklasse besitzt. Methoden, die von Object definiert werden, können von jedem Java-Objekt aufgerufen werden.
Weil jede Klasse eine Superklasse besitzt, formen Klassen in Java eine Klassenhierarchie, die als
Baum mit Object als Wurzel dargestellt werden kann.
3.9.5.
Subklassen-Konstruktoren
Aufrufen eines Konstruktors aus der Superklasse:
Arbeiten mit Java
Prof.Dr. Alois Schütte
39/65
public GraphicCircle(double x, double y, double r, Color outline, Color fill)
{
super(x,y,r);
this.outline = outline;
this.fill = fill;
}
Das Schlüsselwort super dient dazu, die Konstruktor-Methode der Superklasse aufzurufen.
Der Konstruktoraufruf der Superklasse muss als 1. Anweisung innerhalb der KonstruktorMethode erscheinen.
Wenn die 1. Anweisung in einem Konstruktor nicht ein explizter Aufruf des Konstruktor der Superklasse mit super ist, dann fügt Java implizit den super()-Aufruf ein:
• Java ruft den Konstruktor der Superklasse ohne Argumente auf.
• Wenn die Superklasse keinen Konstruktor ohne Argumente hat kommt es zu einem Übersetzungsfehler .
Weil der Superklassen-Konstruktor immer zuerst aufgerufen wird, wird immer als erstes der Object-Konstruktor aufgerufen, gefolgt von der Subklasse und der Klassenhierarchie hinunter zu
der Klasse, die instanziert wurde.
Ist kein Konstruktor in einer Klasse deklariert, wird der Standardkonstruktor aufgerufen, der
wiederum nichts anderes macht, als den Superklassenkonstruktor aufzurufen.
Arbeiten mit Java
Prof.Dr. Alois Schütte
40/65
3.9.6.
Abstrakte Klasssen und Schnittstellen
Eine abstract-Methode in Java entspricht in etwa einer "rein virtuellen" Funktion in C++, d.h. eine virtuelle Funktion, die als = 0 deklariert ist. Javaklassen, die abstract-Methoden enthalten,
können nicht instanziert werden. Ist eine Methode abstract definiert, muss sie nicht implementiert werden.
Regeln für abstract-Methoden und abstract-Klassen:
•
•
•
•
jede Klasse, die eine abstract-Methode enthält ist automatisch selbst abstract
eine abstract-Klasse muss mindestens eine abstract-Methode enthalten
eine abstract-Klasse kann nicht instanziert werden
eine Subklasse der abstract-Klasse kann instanziert werden, wenn sie alle abstractMethoden ihrer Superklasse überschreibt und eine Implementierung für diese Methoden
zur Verfügung stellt
• wenn eine Subklasse einer abstract-Klasse nicht alle abstract-Methoden, die sie erbt, implementiert, dann ist sie selbst abstract
3.9.7.
Schnittstellen
In Java dürfen Klassen nur eine Superklasse besitzen, das bedeutet, dass die von C++ bekannte Mehrfachvererbung nicht möglich ist. Stattdessen kennt Java die so genannten Interfaces. Das sind reine Schnittstellen, die keinerlei Implementierungen enthalten.
Eine Schnittstelle sieht aus wie eine abstrakte Klasse, außer, dass sie das Schlüsselwort interface statt den Wörtern abstract und class benutzt. Alle Methoden in einer Schnittstelle sind implizit abstract. Jede Variable, die in einer Schnittstelle deklariert ist, muss static und final sein .
Arbeiten mit Java
Prof.Dr. Alois Schütte
41/65
Eine Klasse kann mit dem Schlüsselwort implements eine oder mehrere Schnittstellen vererben.
Diese Klasse erbt alle Konstanten und die abstrakten Methoden. Die Methoden müssen dann überschrieben werden.
Beispiel:
interface W{}
interface X extends W {}
class Y implements W {}
class Z extends Y implements X {}
3.9.8.
Schnittstellen erweitern
Schnittstellen können Subschnittstellen besitzen. Eine Subschnittstelle erbt alle abstrakten Methoden und Konstanten seiner Superschnittstelle und kann neue abstrakte Methoden und Konstanten definieren.
Eine Schnittstelle, die mehr als eine Schnittstelle erweitert, erbt alle abstrakten Methoden und
Konstanten aller Schnittstellen und kann neue abstrakte Methoden und Konstanten definieren.
Eine Klasse, die solch eine Schnittstelle implementiert, muss alle abstrakten Methoden, die in
der Schnittstelle selbst definiert sind, und alle Methoden, die von allen Superschnittstellen geerbt
wurden, implementieren.
Arbeiten mit Java
Prof.Dr. Alois Schütte
42/65
4.
Java Beispiele
Durch die folgenden Beispiele von Java Anwendungen werden einige Techniken der Java Programmierung gezeigt, die das Bearbeiten der Übungen im Praktikum erleichtern sollen.
ƒ I/O
ƒ Interfaces
4.1. I/O
Hier soll kurz erklärt werden, wie auf externe Medien geschrieben, bzw. von ihnen gelesen werden kann. Um von externen Medien zu Lesen oder darauf zu schreiben existiert das Konzept der
Streams:
Arbeiten mit Java
Prof.Dr. Alois Schütte
43/65
Source
…
I
n
f
o
a
m
t
o
i
n
Program
read
…
Stream
Program
write
…
I
n
f
o
m
a
t
i
o
n
…
Dest.
Unabhängig davon woher die Daten kommen (Datei, Pipe, Netzwerk) und welchen Typ sie haben
ist das Verfahren des sequentiellen Lesens und Schreibens immer das gleiche:
Lesen
Schreiben
open Stream
while (more information)
read (information)
close Stream
open Stream
while (more information)
write (information)
close Stream
Arbeiten mit Java
Prof.Dr. Alois Schütte
44/65
Das Paket java.io beinhaltet Stream-Klassen, um diese Lese- und Schreiboperationen durchzuführen.
Die Stream-Klassen sind unterteilt nach den grundlegenden Datentypen, die behandelt werden:
• Charakter Streams
Reader und Writer sind abstrakte Superklassen um 16 Bit Zeichen zu Lesen und zu Schreiben. Damit lassen der komplette Unicode Zeichensatz behandeln.
• Byte-Streams
InputStream und OutputStream sind Klassen zum byte-weisen Lesen und Schreiben. Diese
Klasen werden normalerweise verwendet um Binärdaten (Sound, Images) zu behandeln.
Die I/O Superklassen definieren die grundlegenden Methoden zum Lesen und Schreiben.
Reader und InputStream definieren ähnliche APIs für unterschiedliche Datentypen.
Reader beinhaltet u.a. folgende Methoden zum Lesen von Zeichen und von Zeichenfeldern:
int read()
int read(char cbuf[])
int read(char cbuf[], int offset, int length)
InputStream definiert die gleichen Methoden für Bytes:
int read()
int read(byte cbuf[])
Arbeiten mit Java
Prof.Dr. Alois Schütte
45/65
int read(byte cbuf[], int offset, int length)
Writer und OutputStream sind das Pendant zum Schreiben.
Writer definiert die Methoden für Zeichen.:
int write(int c)
int write(char cbuf[])
int write(char cbuf[], int offset, int length)
OutputStream defineert die gleichen Methoden für Bytes:
int write(int c)
int write(byte cbuf[])
int write(byte cbuf[], int offset, int length)
Alle Streams (Reader, Writer, inputStream, OutputStream) werden automatisch geöffnet
wenn sie erzeugt werden. Sie können explizite durch die Methode close geschlossen werden.
Der Garbage Collector schließt Streams implizite, wenn die Objekte nicht mehr benötigt werden.
4.1.1.
Übersicht über Streams
Die folgende Tabelle gibt einen Überblick über das Package java.io:
Arbeiten mit Java
Prof.Dr. Alois Schütte
46/65
Typ of I/O
Streams
Description
CharArrayReader
CharArrayWriter
Use these streams to read from and write to
memory. You create these streams on an existing
array and then use the read and write methods to
read from or write to the array.
ByteArrayInputStream
ByteArrayOutputStream
Memory
StringReader
StringWriter
StringBufferInputStream
Pipe
Arbeiten mit Java
PipedReader
PipedWriter
PipedInputStream
PipedOutputStream
Prof.Dr. Alois Schütte
Use StringReader to read characters from a
String in memory. Use StringWriter to write to
a String. StringWriter collects the characters
written to it in a StringBuffer, which can then be
converted to a String.
StringBufferInputStream is similar to StringReader, except that it reads bytes from a
StringBuffer.
Implement the input and output components of a
pipe. Pipes are used to channel the output from
one thread into the input of another. See PipedReader and PipedWriter in action in the section
How to Use Pipe Streams.
47/65
File
Concatenation
Object
Serialization
Data
Conversion
Counting
Arbeiten mit Java
FileReader
FileWriter
FileInputStream
FileOutputStream
N/A
SequenceInputStream
Collectively called file streams, these streams are
used to read from or write to a file on the native
file system. The section How to Use File Streams.
has an example that uses FileReader and FileWriter to copy the contents of one file into another.
Concatenates multiple input streams into one input stream. The section How to Concatenate Files.
has a short example of this class.
N/A
ObjectInputStream
ObjectOutputStream
Used to serialize objects. See Object Serialization.
N/A
DataInputStream
DataOutputStream
Read or write primitive data types in a machineindependent format. See How to Use DataInputStream and DataOutputStream. shows an example of using these two streams.
LineNumberReader
Keeps track of line numbers while reading.
Prof.Dr. Alois Schütte
48/65
LineNumberInputStream
Peeking Ahead
Printing
Buffering
Filtering
Arbeiten mit Java
PushbackReader
PushbackInputStream
PrintWriter
PrintStream
BufferedReader
BufferedWriter
BufferedInputStream
BufferedOutputStream
FilterReader
FilterWriter
FilterInputStream
FilterOutputStream
Prof.Dr. Alois Schütte
These input streams each have a pushback buffer.
When reading data from a stream, it is sometimes
useful to peek at the next few bytes or characters
in the stream to decide what to do next.
Contain convenient printing methods. These are
the easiest streams to write to, so you will often
see other writable streams wrapped in one of
these.
Buffer data while reading or writing, thereby reducing the number of accesses required on the
original data source. Buffered streams are typically more efficient than similar nonbuffered
streams and are often used with other streams.
These abstract classes define the interface for filter streams, which filter data as it's being read or
written. The section Working with Filter Streams
shows you how to use filter streams and how to
implement your own.
49/65
A reader and writer pair that forms the bridge between byte streams and character streams.
Converting beInputStreamReader
tween Bytes and OutputStreamWriter
Characters
An InputStreamReader reads bytes from an InputStream and converts them to characters, using
the default character encoding or a character encoding specified by name.
An OutputStreamWriter converts characters to
bytes, using the default character encoding or a
character encoding specified by name and then
writes those bytes to an OutputStream.
You can get the name of the default character encoding by calling System.getProperty
("file.encoding").
Die Beispiele werden Streams Verarbeitung für File I/O verdeutlichen.
4.2. File Streams
Die Filestreams FileReader, FileWriter, FileInputStream und FileOutputStream sind zum Zugriff
auf das Dateisystem entwicklet worden.
Das folgende Programm ist eine Implementierung eines Kopierprogramms für Dateien:
Arbeiten mit Java
Prof.Dr. Alois Schütte
50/65
$ cat copy.java
import java.io.*;
public class copy {
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.err.println("usage: copy sourceFile destFile");
return;
}
File inputFile = new File(args[0]);
File outputFile = new File(args[1]);
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
}
$
}
in.close();
out.close();
Arbeiten mit Java
Prof.Dr. Alois Schütte
51/65
Zunächst werden zwei Files deklariert; dann zwei Reader (in und out) erzeugt. Dann wird solange
von in gelesen und auf out geschrieben, bis das Lesen das Dateiende erreicht.
Das Programm, das ebenfalls kopiert, aber mit Bytes anstelle von Zeichen arbeitet, ist analog,
es verwendet einfach FileInputStreams und FileOutputStreams:
Arbeiten mit Java
Prof.Dr. Alois Schütte
52/65
$ cat copyBytes.java
import java.io.*;
public class copyBytes {
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.err.println("usage: copy sourceFile destFile");
return;
}
File inputFile = new File(args[0]);
File outputFile = new File(args[1]);
FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
}
$
}
in.close();
out.close();
4.3. Filter Streams
Arbeiten mit Java
Prof.Dr. Alois Schütte
53/65
Das Package java.io stellt eine Menge von abstrakten Klassen zur Verfügung, um Filter zu realisieren. Ein Filterstream filtert Daten eines zugrunde liegenden Stream.
Die Art des Filterns hängt vom jeweiligen Filterstream ab: es existieren Filtersreams die Zählen,
Puffern und Konvertieren von Daten.
Das folgende Beispiel verdeutlicht DataInputStream und DataOutputStream um Daten auf eine
Datei durch Tabulator getrennt zu schreiben bzw. zu lesen.
Die Daten werden wie folgt (allerdings nicht im ASCII Format) abgelegt:
Preis \t
19.99
9.99
Menge \t
12
8
Beschreibung
Java T-shirt
Java Cup
Das Beispielprogramm schreibt zuerst Daten in der o.a. Form in die Datei „invoice1.txt“. Dann
werden die Daten von der Datei gelesen und ausgegeben.
Hierzu wird DataOutputStream einem zugrundeliegenden OutputStream angehängt, in diesem
Fall dem FileOutputStream .
DataOutputStream out = new DataOutputStream(
new FileOutputStream("invoice1.txt")
);
Nun können Methoden von DataOutputStream verwendet werden, um die Datei zu schreiben:
Arbeiten mit Java
Prof.Dr. Alois Schütte
54/65
double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
int[] units = { 12, 8, 13, 29, 50 };
String[] descs = { "Java T-shirt",
"Java Cup",
"Java JDK",
"Java Pin",
"Java Key Chain" };
for (int i = 0; i < prices.length; i ++) {
out.writeDouble(prices[i]);
out.writeChar('\t');
out.writeInt(units[i]);
out.writeChar('\t');
out.writeChars(descs[i]);
out.writeChar('\n');
}
Um die Daten aus der Datei zu lesen, wird ein DataIntputStream verwendet; er benutzt als
zugrunde liegendem Stream FileIntputStream.
Dann werden die Variablen definiert, um die gelesenen Daten abzulegen.
Arbeiten mit Java
Prof.Dr. Alois Schütte
55/65
// read it in again
DataInputStream in = new DataInputStream(new
FileInputStream("invoice1.txt")
);
double price;
int unit;
StringBuffer desc;
double total = 0.0;
Nun kann die Datei bis zum Ende gelesen werden:
Arbeiten mit Java
Prof.Dr. Alois Schütte
56/65
try {
while (true) {
price = in.readDouble();
in.readChar();
// throws out the tab
unit = in.readInt();
in.readChar();
// throws out the tab
char chr;
desc = new StringBuffer(20);
char lineSep = System.getProperty("line.separator").charAt(0);
while ((chr = in.readChar()) != lineSep)
desc.append(chr);
System.out.println("You've ordered " +
unit + " units of " +
desc + " at $" + price
);
total = total + unit * price;
}
} catch (EOFException e) { }
System.out.println("For a TOTAL of: $" + total);
in.close();
Die While-Schleife bricht ab, wenn ein „in.readXX“ eine Ausnahme erzeugt.
Das gesamte Programm mit der erzeugten Ausgabe ist im Folgenden dargestellt:
Arbeiten mit Java
Prof.Dr. Alois Schütte
57/65
$ cat DataIODemo.java
import java.io.*;
public class DataIODemo {
public static void main(String[] args) throws IOException {
// write the data out
DataOutputStream out = new DataOutputStream(new
FileOutputStream("invoice1.txt"));
double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
int[] units = { 12, 8, 13, 29, 50 };
String[] descs = { "Java T-shirt",
"Java Cup",
"Java JDK",
"Java Pin",
"Java Key Chain" };
for (int i = 0; i < prices.length; i ++) {
out.writeDouble(prices[i]);
out.writeChar('\t');
out.writeInt(units[i]);
out.writeChar('\t');
out.writeChars(descs[i]);
out.writeChar('\n');
}
out.close();
Arbeiten mit Java
Prof.Dr. Alois Schütte
58/65
// read it in again
DataInputStream in = new DataInputStream(new
FileInputStream("invoice1.txt"));
double price;
int unit;
StringBuffer desc;
double total = 0.0;
try {
while (true) {
price = in.readDouble();
in.readChar();
// throws out the tab
unit = in.readInt();
in.readChar();
// throws out the tab
char chr;
desc = new StringBuffer(20);
char lineSep = System.getProperty("line.separator").charAt(0);
while ((chr = in.readChar()) != lineSep)
desc.append(chr);
System.out.println("You've ordered " +
unit + " units of " +
desc + " at $" + price);
total = total + unit * price;
}
} catch (EOFException e) { }
System.out.println("For a TOTAL of: $" + total);
Arbeiten mit Java
Prof.Dr. Alois Schütte
59/65
in.close();
}
}
$
$ java DataIODemo
You've ordered 12 units of Java T-shirt at $19.99
You've ordered 8 units of Java Cup at $9.99
You've ordered 13 units of Java JDK at $15.99
You've ordered 29 units of Java Pin at $3.99
You've ordered 50 units of Java Key Chain at $4.99
For a TOTAL of: $892.8800000000001
$
4.4. Interfaces
Ein Interface ist eine benannte Menge von Methoden-Definitionen ohne Implementierung und
ggf. Konstantendefinitionen.
Somit hat ein Interface Ähnlichkeit zu abstrakten Klassen. Die Unterschiede sind:
• Ein Interface kann eine Methode nicht implementieren – eine abstrakte Klasse kann dies.
• Eine Klasse kann mehrere Interfaces implementieren aber nur eine Superklasse haben (keine Mehrfachvererbung).
• Ein Interface ist nicht Bestandteil der Klassenhierarchie. Nicht in Beziehung stehende Klassen können dasselbe Interface implementieren.
Arbeiten mit Java
Prof.Dr. Alois Schütte
60/65
Im Folgenden wird ein Beispiel betrachtet, bei dem eine Klasse (StockMonitor) zu realisieren
ist, die Aktienkurse überwacht, die über eine Datenleitung von einem Kurslieferanten gelesen
werden.
Diese Klasse erlaubt es anderen Klassen zu registrieren, dass die Klassen informiert werden wollen, wenn eine Aktie einen Schwellwert übersteigt.
Die Klasse StockMonitor implementiert eine Methode watchStock mit der andere Klassen die
Überwachung einer Aktie (tickerSysmbol) Registrieren können:
Arbeiten mit Java
Prof.Dr. Alois Schütte
61/65
public class StockMonitor {
public void watchStock(StockWatcher watcher, // interface name
String tickerSymbol, // ticker symbol
double delta
) {
...
}
}
Das erste Argument der Methode watchStock ist der Name eines Interface:
public interface StockWatcher {
final String sunTicker = "SUNW";
…
void valueChanged(String tickerSymbol, double newValue);
}
Dieses Interface deklariert eine Methode valueChanged. Ein Objekt, das bei Änderung des Aktienkurses informiert werden will, muss ein Exemplar der Klasse sein, die das Interface implementiert.
Durch das erste Argument die Methode watchStock der Klasse StockMonitor wird sicher gestellt, dass alle Objekte die Methode valueChanges implementieren müssen.
Hätte man anstelle eines Interface StockWatcher eine Klasse verwendet, so wäre die Verwendung nur von Objekten, die aus StockWatcher abgeleitet werden, möglich.
Arbeiten mit Java
Prof.Dr. Alois Schütte
62/65
Durch die Verwendung des Interface, kann der Dienst von jeder Klasse in der Klassenhierarchie
verwendet werden (z.B. Applet, Thread, ….).
4.4.1.
Definition eines Interface
Die Definition eines Interface besteht aus
• Interface Deklaration
• Interface Körper
Intercace
Declaration
public interface StockWatcher {
final String
sunTicker = "SUNW";
final String oracleTicker = "ORCL";
final String ciscoTicker = "CSCO";
Body
Constant
Declarations
Method
void valueChanged(String tickerSymbol, double newValue); Declarations
}
Interface Deklaration
Die Komponenten der Interface Deklaration sind:
Arbeiten mit Java
Prof.Dr. Alois Schütte
63/65
• public
dadurch wird das Interface pubic-verfügbar
• interface <Name>
definiert den Namen des Interface
• extends <SuperInterface1>, …<SuperInterfaceN>
ein Interface kann mehrere Super-Interfsces haben (im Gegensatz zu Klassen).
Interface Körper
Die Komponenten des Interface Körper sind:
• Konstanten Definitionen
sind implizite public, static und final.
• Methoden Deklarationen
werden durch „;“ getrennt und sind implizit public und abstract.
4.4.2.
Implementierung eines Interface
Ein Interface beschreibt ein Verhalten von Objekten. Eine Klasse, die das Interface implementiert setzt das gewünschte Verhalten der Objekte um.
Um eine Klasse, die ein Interface implementiert zu realisieren, wird bei der Klassendeklaration
das Inteface durch „implements“ angegeben:
Arbeiten mit Java
Prof.Dr. Alois Schütte
64/65
public class StockApplet extends Applet implements StockWatcher {
...
public void valueChanged(String tickerSymbol, double newValue) {
if (tickerSymbol.equals(sunTicker)) {
... // get Data from Datafeed for SUN
} else if (tickerSymbol.equals(oracleTicker)) {
... // get Data from Datafeed for ORACLE
} else if (tickerSymbol.equals(ciscoTicker)) {
... // get Data from Datafeed for CISCO
}
}
}
Arbeiten mit Java
Prof.Dr. Alois Schütte
65/65
Herunterladen