155
Einführung in Java Hochschule für Angewandte Wissenschaften Hamburg Thomas Klinker Hamburg University of Applied Sciences Department Informations- und Elektrotechnik 02.2008 /* * The HelloWorldApp class implements an * application that simply displays * "Hello World!" to the standard output. */ class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } }

bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

Embed Size (px)

Citation preview

Page 1: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

Einführung in Java

Hochschule für Angewandte Wissenschaften Hamburg Thomas Klinker Hamburg University of Applied Sciences Department Informations- und Elektrotechnik 02.2008

/*

* The HelloWorldApp class implements an

* application that simply displays

* "Hello World!" to the standard output.

*/

class HelloWorldApp {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

Page 2: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

Inhalt

1 OOP I : Klassen und Objekte ______________________________________________ 5

1.1 Erste Java-Programme_____________________________________________________ 5

1.2 Einführung in Klassen und Objekte __________________________________________ 8

2 Grundelemente von Java_________________________________________________ 20

2.1 Datentypen, Namen, Felder ________________________________________________ 20

2.2 Die Collection ArrayList __________________________________________________ 28

2.3 Kontrollstrukturen _______________________________________________________ 32

2.4 Operatoren _____________________________________________________________ 33

2.5 Ausnahmebehandlung (Exception-Handling) _________________________________ 36

2.6 Einfache Ein- und Ausgabe ________________________________________________ 40

2.7 Parameterübergabe bei Methoden __________________________________________ 45

2.8 Zuweisung von Objekten __________________________________________________ 46

2.9 Vergleich von Objekten ___________________________________________________ 49

2.10 Übungsaufgaben _______________________________________________________ 51

3 OOP II : Vererbung_____________________________________________________ 53

3.1 Das Konzept der Vererbung _______________________________________________ 53

3.2 Die Basisklasse Object ____________________________________________________ 63

3.3 Typkonvertierung in Vererbungshierarchien _________________________________ 65

3.4 Verwendung des Operators instanceof____________________________________ 66

3.5 Pakete und Sichtbarkeit ___________________________________________________ 67

3.6 Übungsaufgaben ________________________________ Fehler! Textmarke nicht definiert.

4 Grafikprogramme, Maus und Tastatur _____________________________________ 73

4.1 Maus- und Tastaturereignisse ______________________________________________ 78 4.1.1 Maus ______________________________________________________________________ 78 4.1.2 Tastatur ____________________________________________________________________ 82

4.2 Übungsaufgaben _________________________________________________________ 85

5 Applets _______________________________________________________________ 86

5.1 Das Einbinden eines Applets _______________________________________________ 89

5.2 Übungsaufgaben _________________________________________________________ 92

6 OOP III : Polymorphie, Abstrakte Klassen und Interfaces ______________________ 94

6.1 Polymorphie und spätes Binden ____________________________________________ 94

6.2 Abstrakte Klassen und Interfaces ___________________________________________ 99

6.3 Das Interface Cloneable _______________________________________________ 101

6.4 Das generische Interface Comparable<T>_________________________________ 106

6.5 Ereignisbehandlung _____________________________________________________ 107

7 Timer und Threads ____________________________________________________ 112

7.1 Timer _________________________________________________________________ 112

Page 3: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

Inhalt 3

7.2 Threads und das Interface Runnable ______________________________________ 115

7.3 Übungsaufgaben ________________________________________________________ 120

8 Swing-Komponenten ___________________________________________________ 121

8.1 Übersicht über die Swing-Komponenten ____________________________________ 121

8.2 JButton und JLabel _____________________________________________________ 123

8.3 Layout-Manager ________________________________________________________ 124

8.4 JDialog und JOptionPane ________________________________________________ 131

8.5 JCheckBox und JRadioButton ____________________________________________ 135

8.6 JTextField, JTextArea und JScrollPane_____________________________________ 136

8.7 JSlider und JProgressbar ________________________________________________ 139

8.8 JMenu und JPopupmenu _________________________________________________ 141

8.9 JFileChooser ___________________________________________________________ 144

8.10 Übungsaufgaben ______________________________________________________ 146

9 Anhang______________________________________________________________ 147

9.1 Schlüsselwörter (keywords) in Java ________________________________________ 147

9.2 Einige Java-Begriffe _____________________________________________________ 147

9.3 Package java.lang _______________________________________________________ 148 9.3.1 Class Summary _____________________________________________________________ 148 9.3.2 Class java.lang.Math _________________________________________________________ 149 9.3.3 Class java.lang.String ________________________________________________________ 150

9.4 Class java.awt.Graphics__________________________________________________ 153

Page 4: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

Literatur

Bücher [1] Krüger, G.: Handbuch der Java-Programmierung. Addison-Wesley 2008. (Download von www.gkrueger.com) [2] Eckel, B.: Thinking in Java. Prentice Hall 2006.

(Download von www.BruceEckel.com) [3] Samaschke, K.: Java 6 – Einstieg für Anspruchsvolle. Addison-Wesley / Pearson Studium 2007. [4] Merker, E. und Merker, R: Programmieren lernen mit Java. Vieweg 2006. [5] Horstmann, C. und Cornell, G: Java, Band 1 – Grundlagen. Addison-Wesley 2005. [6] Louis, D. und Müller, P: Jetzt lerne ich Java 6. Markt + Technik 2007. [7] Flanagan, D.: Java in a Nutshell. Deutsche Ausgabe für Java 1.2 und 1.3. O'Reilly 2000

Tutorial [8] Java Tutorial. (java.sun.com/docs/books/tutorial/)

Entwicklungswerkzeuge [9] Eclipse SDK 3.0.2. (Download von www.eclipse.org/downloads/) [10] Java Development Kit. (Download von java.sun.com) [11] Java Hilfe Dateien. (Download von java.sun.com/docs/)

Page 5: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte

Die objektorientierte Programmiersprache Java wurde beginnend Mitte der 90er Jahren bei Sun Microsystems entworfen. − Java greift in seinen grundlegenden Datentypen und Kontrollstrukturen auf C zurück. − Die objektorientierten Konstrukte erinnern an C++. Im Detail unterscheidet sich Java aber

recht deutlich von C++. − Applets sind Java-Pogramme, die im Fenster eines HTML-Browsers ausgeführt und dar-

gestellt werden können.

1.1 Erste Java-Programme

Ein erstes Java-Programm

Datei "Hello.java"

/* * The Hello class implements an application that simply * displays "Hello World!" to the standard output */

public class Hello { public static void main(String[] args) { System.out.println("Hello World!"); //Display the string } }

Auf der Konsole Hello World!

Das Java-Programm besteht aus der Klasse (class) "Hello", die hier lediglich die Methode "main" enthält. Die Ausführung des Programms beginnt bei "main", so wie man es von C her kennt. Die "main" vorausgehenden Schlüsselwörter haben die folgenden Bedeutungen:

− "public" bewirkt, dass die Methode "main" auch außerhalb der Klasse bekannt ist. − "static" hat zur Folge, dass "main" aufgerufen werden kann, ohne dass eine Instanz der

Klasse angelegt werden muss (vgl. Abschnitt 1.2). − "void" zeigt, dass "main" keinen Funktionswert zurückgibt.

Die Methode "main" übernimmt als einzigen Parameter immer ein Feld mit Elementen vom Datentyp "String" (Zeichenkette). Jeder "String" im Feld enthält ein Kommandozeilen-argument (vgl. Abschnitt 2). In "main" wird die Methode "println" aus der Klasse "System" aufgerufen. Diese Klasse enthält unter anderem Methoden zur Ausgabe ("out").

Wichtig: − Groß-/Kleinschreibung wird beachtet. − Der Quelltext muss in einer Datei "<Name der Klasse>.java" gespeichert werden. − Die Ausgabedatei des Compilers heißt dann "<Name der Klasse>.class", und enthält

Java-Bytecode und nicht etwa Maschinenbefehle für den jeweiligen Prozessor.

Page 6: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 6

Java Bytecode

Java APIs

Java Virtual Machine

PC (Windows/Linux/...)

JDK (Java Development Kit)

Im JDK [6] sind ein Compiler "javac", ein Interpreter "java", ein Appletbetrachter "applet-viewer" und weitere Programme enthalten.

Übersetzung und Ausführung von "Hello.java" mit dem JDK

javac Hello.java (→ Java-Bytecode in "Hello.class")

java Hello (Und nicht "java Hello.class")

1995: JDK 1.0 (1.0.2) Einfache Implementierung mit einer Reihe von Unzulänglichkeiten, grundlegende Änderun-gen waren notwendig. Folge: Viele nicht mehr aktuelle Methoden und Klassen (deprecated, missbilligen, bemäkeln).

1997: JDK 1.1 (1.1.7) Geändertes Ereignis-Modell für die Benutzeroberfläche (GUI, Graphical User Interface), viele neue Klassenbibliotheken.

1999: JDK 1.2 (1.2.2) Ab hier "Java 2 Plattform", neue GUI-Klassenbibliothek (Swing), neue Container-Klassen.

2000: JDK 1.3 (1.3.1) Fehlerbereinigung, neuer Interpreter (Hotspot Virtual Machine).

2002: JDK 1.4 (1.4.2) Verbesserte Performance, Unterstützung von Mausrad und "drag-and-drop".

2004: JDK 1.5 Zahlreiche Verbesserungren.

Die Java-Plattform

Bild 1.1 zeigt, dass die Java-Umgebung aus den Programmier- und Anwendungsschnittstellen (Application Programming Interfaces, APIs) und der Java Virtuellen Maschine (JVM) besteht.

Bild 1.1 Umgebung bei der Ausführung von Java-Bytecode

− Java APIs sind Bibliotheken mit kompiliertem Code, die von Java-Programmen ein-gesetzt werden können. Das "Hello" Programm verwendet zum Beispiel ein Java API, um den Text "Hello World!" auszugeben.

− Java-Bytecode wird von der Java VM interpretiert. Java-Programme laufen also nicht unmittelbar auf dem jeweiligen Prozessor.

Vorteil: "Cross Plattform Design", also bessere Portierbarkeit. Nachteil: Java-Programme werden langsamer als kompilierte Programme ausgeführt.

Page 7: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 7

Ein erstes Java-Applet

Datei "HelloApplet.java"

// Provides the classes necessary to create an applet and // the classes an applet uses to communicate with its applet // context import java.applet.*; // Contains all of the classes for painting graphics and // images (awt = abstract windows toolkit) import java.awt.*; public class HelloApplet extends Applet { public void paint(Graphics g) { g.drawString("Hello World!", 25, 50); } }

Mit "import" werden für das Applet benötigte Bibliotheken importiert. Das Applet besteht aus der Klasse "HelloApplet", erweitert (extends) die Klasse "Applet" (vgl. Abschnitt 3.1) und enthält hier lediglich die Methode "paint". Diese Methode wird von einem Appletviewer oder von einem Web Browser aufgerufen und ist dazu gedacht, grafische Ausgaben zu erzeugen, also z.B. Texte oder Linien zu zeichnen. Der Parameter "g" liefert den Bezug zum grafischen Kontext der Umgebung und wird hier verwendet, um die Zeichenkette "Hello World!" ab dem linken, unteren Anfangspunkt x = 25 und y = 50 auszugeben. Die Datei "HelloApplet.java" muss kompiliert werden, und als Ergebnis entsteht die Datei "HelloApplet.class", die Java Bytecode enthält.

Datei "HelloApplet.html"

<HTML> <APPLET CODE="HelloApplet.class" WIDTH=400 HEIGHT=300> </APPLET> </HTML>

Um das Applet vom Applet-viewer oder vom Web Browser darstellen zu lassen, wird eine kleine HTML Datei (Hyper Text Markup Language) benötigt, die denselben Namen wie das Applet haben sollte. In dieser Datei stellt das sogenannte APPLET Tag (Kennung, Markierung) einen Bezug zum Applet her. Darüber hinaus werden Breite und Höhe des Ausgabefläche festgelegt.

Bild 1.2 Ausgabe im Web-Browser

Page 8: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 8

Aufgabe 1.1 Auf der Konsole soll der folgende Text ausgegeben werden.

Fb E/I Hamburg

a) Schreiben Sie ein Java Programm "Display.java". b) Schreiben Sie ein Applet "DisplayApplet.java" und eine geeignete HTML Datei

"DisplayApplet.html".

1.2 Einführung in Klassen und Objekte

− Ein Java-Programm besteht aus einer Klasse oder aus mehreren miteinander verbundenen Klassen.

− Mit einer Klasse werden Eigenschaften und Fähigkeiten von Objekten beschrieben. Beispiel, Circle1 public class Circle1 { double radius; double area() {return 3.14159 * radius * radius;} public static void main(String[] args) {

//Or "Circle1 circle = new Circle1();" Circle1 circle; circle = new Circle1();

circle.radius = 1.5; System.out.println("Circle area: " + circle.area()); } }

Auf der Konsole Circle area: 7.068577499999999

Die Definition der Klasse "Circle1" enthält eine Variable ("radius") und Methoden ("area", "main"). Die Klasse "Circle1" stellt einen neuen Datentyp dar. Circle1 circle;

Bei der Ausführung der Anweisung wird eine Referenz auf eine Instanz (ein Exemplar) der Klasse "Circle1" angelegt (Bild 1.3). circle = new Circle1(); Mit dem Schlüsselwort "new" wird ein Objekt zur Laufzeit des Programms dynamisch erzeugt. Ein Objekt ist eine Instanz einer Klasse. Die Objektvariable "circle" verweist nun also auf ein Objekt vom Datentyp "Circle1" (Bild 1.4).

circle

Bild 1.3 Referenz

Page 9: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 9

circle

Eine Instanz der Circle1-Klasse, also ein Objekt vom Datentyp Circle1

Bild 1.4 Die Variable "circle" verweist nun auf ein Objekt vom Typ "Circle1" circle.radius = 1.5; Der Variablen "radius" des Objekts auf das "circle" verweist, oder kurz "radius" von "circle", wird ein Wert zugewiesen. System.out.println("Circle area: " + circle.area());

Die Methode "area" wird auf das Objekt "circle" angewendet (Objektorientierte Program-mierung), es wird also die Fläche von "circle" berechnet. Der Rückgabewert wird hier selbsttätig in eine Zeichenkette umgewandelt und danach mit dem Ausgabetext "Circle area: " verkettet (Operator "+"). double area() {return 3.14159 * radius * radius;}

Das Objekt "circle", auf das die Methode hier angewendet wird, wird automatisch übergeben. Mit "radius" ist dann also der Radius von "circle" gemeint. Es ist überflüssig und unzulässig "circle.radius" zu schreiben.

Konstruktor

circle = new Circle1();

Das Klammernpaar in der Anweisung deutet auf den Aufruf einer Methode hin, und es wird tatsächlich eine spezielle Methode aufgerufen, die Konstruktor genannt wird. Jede Klasse in Java besitzt mindestens einen Konstruktor. Die Aufgabe eines Konstruktors ist es, ein neues Objekt zu initialisieren. Da die Klasse "Circle1" keinen Konstruktor enthalten hat, ist von Java automatisch ein leerer1 Standardkonstruktor angelegt worden.

Beispiel, Circle2

public class Circle2 { double radius; // Konstruktor Circle2(double r) {radius = r;} double area() {return 3.14159 * radius * radius;} public static void main(String[] args) { Circle2 circle = new Circle2(1.5); System.out.println("Circle area: " + circle.area()); } }

Auf der Konsole Circle area: 7.068577499999999

1 Der Standardkonstruktor enthält genau genommen einen Aufruf des Konstruktors der Oberklasse (vgl. Abschnitt 3.1).

Page 10: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 10

Ein Konstruktor hat immer den gleichen Namen wie seine Klasse, im vorausgehenden Beispiel also "Circle2". Beim Anlegen des neuen Objekts "circle" in der Zeile

Circle2 circle = new Circle2(1.5);

wird automatisch der Konstruktor aufgerufen, und "radius" von "circle" wird hier mit dem Wert "1.5" initialisiert.

Aufgabe 1.2 public class Cube { int dim1, dim2, dim3; ... ... public static void main(String[] args) { Cube cube1 = new Cube(1, 2, 3); System.out.println("Volume of cube1: " + cube1.volume()); Cube cube2 = new Cube(4, 5, 6); System.out.println("Volume of cube2: " + cube2.volume()); } }

Auf der Konsole Volume of cube1: 6 Volume of cube2: 120

Vervollständigen Sie das Programm so, dass es die gegebenen Daten ausgibt.

Mehrere Konstruktoren

Beispiel, Circle3

public class Circle3 { double radius;

Circle3(double r) {radius = r;}

// Standard constructor (empty) Circle3() {}

double area() {return 3.14159 * radius * radius;}

public static void main(String[] args) { Circle3 c1 = new Circle3(1.5); Circle3 c2 = new Circle3();

// Copy object c2 = c1;

System.out.println("Area of c2: " + c2.area()); } }

Page 11: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 11

Auf der Konsole Area of c2: 7.068577499999999

Eine Klasse kann mehrere Konstruktoren besitzen, die dann alle den gleichen Namen wie ihre Klasse haben. Sie müssen sich aber in den Datentypen und/oder in der Reihefolge der Daten-typen ihrer Parameter unterscheiden, damit der Compiler den jeweils aufzurufenden Konstruktor eindeutig feststellen kann. Methoden mit dem gleichen Namen aber sich unterscheidenden Parameterlisten zu definieren, wird Überladen (Overloading) von Methoden genannt. Datenkapselung Im folgenden Beispiel ist eine Klasse Rect zur Beschreibung von Rechtecken implementiert. Breite und Höhe können über die Methoden setWidth() und setHeight() geändert werden. Die Fläche wird automatisch neu berechnet. Der direkte Zugriff auf die Membervariablen width und height ist aber immer noch möglich. Dadurch kann eine Instanz der Klasse Rect in einen Zustand gebracht werden, in dem die Membervariable area nicht mehr den korrekten Wert enthält. Beispiel, MyRectApp1 /* Klasse MyRectApp1 * Verstoss gegen Datenkapselung * */ class Rect{ double width, height; double area; double getArea(){ return area; } void setWidth(double width){ this.width=width; calculateArea(); } void setHeight(double height){ this.height=height; calculateArea(); } void calculateArea(){ area = width*height; } } public class MyRectApp1{ public static void main(String s[]){ Rect r = new Rect(); System.out.println("area: " + r.getArea()); r.setWidth(1.0);

Page 12: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 12

r.setHeight(3.0); System.out.println("area: " + r.getArea()); r.width=0.5; System.out.println("area: " + r.getArea()); } }

Auf der Konsole area: 0.0 area: 3.0 area: 3.0 Um die Klasse Rect als brauchbare Software nutzen zu können, werden die Member-variablen mit dem Modifikator private vor dem direkten Zugriff geschützt: Beispiel, MyRectApp2 /* Klasse MyRectApp2 * Kein Verstoss mehr gegen Datenkapselung * */ class Rect{ private double width, height; private double area; double getArea(){ return area; } void setWidth(double width){ this.width=width; calculateArea(); } void setHeight(double height){ this.height=height; calculateArea(); } void calculateArea(){ area = width*height; } } public class MyRectApp2{ public static void main(String s[]){ Rect r = new Rect(); System.out.println("area: " + r.getArea()); r.setWidth(1.0); r.setHeight(3.0); System.out.println("area: " + r.getArea()); r.setWidth(0.5); System.out.println("area: " + r.getArea()); } }

Page 13: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 13

Auf der Konsole area: 0.0 area: 3.0 area: 1.5 Klassenvariablen (static)

Beispiel, MyCircleApp4 /* MyCircleApp4 * Verwendung von Klassenvariablen (static) * */ class Circle { // Klassenvariable numberOfCircles static int numberOfCircles = 0; private double radius; Circle(double r) { radius = r; numberOfCircles++; } double area() {return 3.14159 * radius * radius;} } public class MyCircleApp4 { public static void main(String[] args) { System.out.println("Number of circles: " + Circle.numberOfCircles); Circle c1 = new Circle(1.0); System.out.println("Number of circles: " + Circle.numberOfCircles); System.out.println(" Area of c1: " + c1.area()); Circle c2 = new Circle(2.0); System.out.println("Number of circles: " + Circle.numberOfCircles); System.out.println(" Area of c2: " + c2.area()); } }

Auf der Konsole Number of circles: 0 Number of circles: 1 Area of c1: 3.14159 Number of circles: 2 Area of c2: 12.56636

In der Klassendefinition gibt es die Instanzvariable radius. Jede Instanz der Klasse, also jedes Objekt, hat eine eigene Kopie dieser Variablen. Neu ist die Klassenvariable numberOfCircles.

Page 14: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 14

− Klassenvariablen werden mit dem Schlüsselwort "static" vereinbart.

− Es existiert nur ein Exemplar von Klassenvariablen, das schon beim Programmstart angelegt wird.

Bild 1.5 verdeutlicht den Unterschied zwischen Klassen- und Instanzvariablen.

Klasse Circle4

numberOfCircles

Objekt c1

radius

Objekt c2

radius

Klassenvariable

Instanzvariablen

Bild 1.5 Klassen- und Instanzvariablen

Konstanten (static final)

Da in Java kein Präprozessor existiert, sind Vereinbarungen der Art "#define MAX 100" nicht zulässig.

Beispiel, MyCircleApp5 /* MyCircleApp5 * Verwendung von Konstanten (static final) * */ class Circle { // Konstante MAXRADIUS static final double MAXRADIUS = 2.0; static int numberOfCircles = 0; private double radius; Circle(double r) { radius = (r <= MAXRADIUS) ? r : MAXRADIUS; numberOfCircles++; } double area() {return 3.14159 * radius * radius;} } public class MyCircleApp5 { public static void main(String[] args) { System.out.println("Number of circles: " + Circle.numberOfCircles); Circle c1 = new Circle(1.0); System.out.println("Number of circles: "

Page 15: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 15

+ Circle.numberOfCircles); System.out.println(" Area of c1: " + c1.area()); Circle c2 = new Circle(3.5); System.out.println("Number of circles: " + Circle.numberOfCircles); System.out.println(" Area of c2: " + c2.area()); } } Auf der Konsole Number of circles: 0 Number of circles: 1 Area of c1: 3.14159 Number of circles: 2 Area of c2: 12.56636

Konstanten werden auf Klassenebene mit dem Schlüsselwort "final" vereinbart. Der Wert wird bei der Vereinbarung zugewiesen und lässt sich danach nicht mehr verändern.

Klassenmethoden (static)

Beispiel, MyCircleApp6 /* MyCircleApp6 * Verwendung von Klassenmethode (static) */ class Circle { private static int numberOfCircles = 0; private double radius; Circle(double r) { radius = r; numberOfCircles++; } // Klassenmethode getNumberOfCircles() static int getNumberOfCircles() { return numberOfCircles; } double area() {return 3.14159 * radius * radius;} } public class MyCircleApp6 { public static void main(String[] args) { System.out.println("Number of circles: " + Circle.getNumberOfCircles()); Circle c1 = new Circle(1.0); System.out.println("Number of circles: " + Circle.getNumberOfCircles()); System.out.println(" Area of c1: " + c1.area());

Page 16: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 16

Circle c2 = new Circle(2.0); System.out.println("Number of circles: " + Circle.getNumberOfCircles()); System.out.println(" Area of c2: " + c2.area()); } }

Auf der Konsole Number of circles: 0 Number of circles: 1 Area of c1: 3.14159 Number of circles: 2 Area of c2: 12.56636

In der Klassendefinition gibt es wie in den vorausgehenden Beispielen die Instanzmethode "area()". Instanzmethoden werden auf Objekte angewendet. Schreibweise: <Objekt>.<Instanzmethode(...)>, z. B. c1.area() Zusätzlich gibt es die Klassenmethode "getNumberOfCircle()". Klassenmethoden werden auf die Klasse angewendet. Schreibweise: <Klasse>.<Klassenmethode(...)>, z. B. Circle.getNumberOfCircles() Zusammenfassend: − Klassenmethoden werden mit dem Schlüsselwort "static" vereinbart. − Da Klassenmethoden unabhängig von konkreten Instanzen der Klasse existieren, ist ein

Zugriff auf Instanzvariablen nicht möglich!

Die Klassenmethode "main()" wird beim Programmstart von der Java-Umgebung aufgerufen.

Mehrere Klassen

Wie schon in einigen Beispielen zuvor werden im folgenden Beispiel mehrere Klassen verwendet. Sie können in einer Datei gespeichert werden. Dann darf nur eine dieser Klassen als "public" deklariert werden, und der Dateinamen muss mit dem Namen dieser Klasse übereinstimmen. Der Compiler erzeugt für jede Klasse eine Ausgabedatei <Klassen-namen>.class. In der Regel sollte jede Klasse in einer eigenen Datei stehen. Beispiel, Circle7 class MyMath { static final double PI = 3.14159; static double square(double value) { return value * value; } } public class Circle7 { double radius; Circle7(double r) {radius = r;}

Page 17: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 17

double area() {return MyMath.PI * MyMath.square(radius);} public static void main(String[] args) { Circle7 circle = new Circle7(1.5); System.out.println("Area of circle: " + circle.area()); } }

Auf der Konsole Area of circle: 7.068577499999999

Das Beispiel zeigt noch einmal, dass Klassenvariablen und Klassenmethoden außerhalb ihrer Klasse mit dem vorgestellten Klassennamen aufgerufen werden.

Die Klasse "Math"

Im Anhang ist ein Überblick über die Klasse "Math" aus dem Paket "java.lang" zu finden. Für dieses grundlegende Paket ist keine Anweisung "import java.lang.*;" erforderlich.

Beispiel, Circle8 public class Circle8 { double radius; Circle8(double r) {radius = r;} double area() {return Math.PI * Math.pow(radius, 2.0);} public static void main(String[] args) { Circle8 circle = new Circle8(1.5); System.out.println("Area of circle: " + circle.area()); } }

Auf der Konsole Area of circle: 7.0685834705770345

Es werden "PI" und "pow" aus der Klasse "Math" eingesetzt, die in der Klasse als "static" deklariert worden sind. In beiden Fällen wird deshalb der Klassenname "Math" angegeben.

Aufgabe 1.3 public class Circle { double radius; static double area(double r) {return Math.PI * Math.pow(r, 2.0);} public static void main(String[] args) { radius = 1.5; System.out.println("Area of circle: " + area(radius)); } }

Page 18: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 18

Fehlermeldungen des Compilers Circle.java:7: non-static variable radius cannot be referenced from a static context radius = 1.5; ^ Circle.java:9: non-static variable radius cannot be referenced from a static context System.out.println("Area of circle: " + area(radius)); ^

Warum gibt der Compiler die Fehlermeldungen aus? Korrigieren Sie das Programm.

Aufgabe 1.4 public class Tabel_a { public static void main(String[] args) { String angleStr, sinStr, cosStr, tanStr; System.out.println("Angle Sin Cos Tan "); System.out.println("------------------------------"); for(int angle = 0; angle <= 60; angle += 10) { double rad = angle * Math.PI / 180.0; angleStr = String.format("%5d", angle); sinStr = String.format("%8.3f", Math.sin(rad)); cosStr = String.format("%8.3f", Math.cos(rad)); tanStr = String.format("%8.3f", Math.tan(rad)); System.out.println( angleStr + sinStr + cosStr + tanStr); } } }

Was gibt das Programm aus? Die Referenz "this" Beim Aufruf einer Instanzmethode wird implizit eine Referenz "this" auf das Objekt über-geben, auf das die Methode angewendet wird. Das folgende Beispiel zeigt, wie man diese Referenz im eigenen Programmcode einsetzen kann. Beispiel, MyRectApp3 /* Klasse MyRectApp3 * Komplett mit getter und setter * */

Page 19: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

1 OOP I : Klassen und Objekte 19

class Rect{ private double width, height; private double area; public double getWidth() { return width; } public double getHeight() { return height; } public double getArea(){ return area; } public void setWidth(double width){ this.width=width; calculateArea(); } public void setHeight(double height){ this.height=height; calculateArea(); } private void calculateArea(){ area = width*height; } } public class MyRectApp3{ public static void main(String s[]){ Rect r = new Rect(); System.out.println("area: " + r.getArea()); r.setWidth(1.0); r.setHeight(3.0); System.out.println("width: " + r.getWidth()); System.out.println("height: " + r.getHeight()); System.out.println("area: " + r.getArea()); } }

Auf der Konsole area: 0.0 width: 1.0 height: 3.0 area: 3.0

Hinweis: Instanzvariablen werden automatisch initialisiert: numerische Variablen auf 0, boolesche Variablen auf false, Strings auf Null-String "", Objekte auf null. Lokale Variablen von Methoden hingegen werden nicht automatisch initialisiert.

Page 20: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java

Kommentare

/** This class displays a text string at * the console */

/* A C-style comment */

public class Hello1 { // Another C-style comment

public static void main(String[] args){ System.out.println("Hello World!"); } }

Java unterstützt drei Kommentarformen:

− Die von C bzw. C++ vertrauten "/* ... */" und "// ..." Kommentare.

− Dokumentationskommentare (doc comments) "/** ... */", die vom Programm "javadoc" ausgewertet werden, um eine einfache Dokumentation zu erstellen.

2.1 Datentypen, Namen, Felder Einfache Datentypen Data Type Description Size/Format Range Integers byte Byte-length integer 8-bit two's compl. -128 to +127 short Short integer 16-bit two's compl. -32 768 to +32 767 int Integer 32-bit two's compl. -2.1�109 to +2.1�109 long Long integer 64-bit two's compl. -9.2�1018 to +9.2�1018 Real Numbers float Single-precision floating point 32-bit IEEE 754 ±3.4�10-38 to ±3.4�1038 double Double-precision floating point 64-bit IEEE 754 ±1.7�10-308 to ±1.7�10308 Other Types char A single character 16-bit Unicode char. boolean A boolean value true or false

Vergleich mit C:

− Java kennt keine vorzeichenlosen Datentypen.

− Es gibt zusätzlich die Datentypen "byte" und "boolean".

− Die Länge von "int" ist auf 32 Bit festgelegt.

− Zeichen (character) werden nicht im 8-Bit ASCII Code sondern im 16-Bit Unicode gespeichert.

− Es existieren keine Zeiger (z.B. "int*").

− Es gibt keine Strukturen ("struct"), keine Bitfelder und keine Unions ("union").

Page 21: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 21

Beispiele für Konstanten Literal Data Type 257 int 0x1AF int 8864L long 37.266 double 37.266D or 37.266d double 87.363F or 87.363f float 26.77e3 double ' c ' char true boolean false boolean

Namen

Namen bestehen aus Buchstaben (Unicode, also auch Umlaute zulässig), Ziffern und den Zeichen '_' (Unterstrich) und '$' (Dollar). Das erste Zeichen darf dabei keine Ziffer sein. Die folgenden Konventionen machen Java-Programme lesbarer. Es ist gute Programmierpraxis sich an diese Namenskonventionen zu halten.

− Die Namen von Variablen und Methoden beginnen mit einem Kleinbuchstaben, neue Wörter innerhalb des Namens mit einem Großbuchstaben.

Variablen: kontoNummer, teilnehmerName, index, temp Methoden: main, paint, getValue, toString

− Die Namen von Klassen beginnen mit einem Großbuchstaben, neue Wörter innerhalb des Namens ebenfalls mit einem Großbuchstaben.

Beispiele: Hello, Echo, HelloApplet, AgeLimit

− Die Namen von Konstanten bestehen aus Großbuchstaben, neue Wörter innerhalb des Namens werden durch einen Unterstrich "_" eingeleitet.

Beispiele: PI, MAX_X_VALUE, HINTERGRUND_FARBE

Beispiel, AgeLimit public class AgeLimit1 { final static int LOWER_AGE_LIMIT = 12; public static void main(String[] args) { int customerAge = 11; String tooYoung = "Too young"; String ageOk = "Age ok"; if(customerAge < LOWER_AGE_LIMIT) // if ... else ... System.out.println(tooYoung); else System.out.println(ageOk); } }

Auf der Konsole Too young

Page 22: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 22

Zeichenketten Zeichenketten (Strings) sind in Java Objekte. Der Name eines Strings ist eine Referenz-variable, die auf den String verweist. Es ist zu beachten, dass durch die Klasse String keine dynamischen Zeichenketten implementiert werden. Nach der Initialisierung eines String-Objektes bleiben dessen Länge und dessen Inhalt konstant. Die einzelnen Zeichen lassen sich also nicht mehr ändern. Es gibt drei Konstruktoren: String() Erzeugt ein leeres String-Objekt. String(String value) Erzeugt ein String-Objekt durch kopieren eines Vorhandenen. String(char[] value) Erzeugt ein String-Objekt aus einem vorhandenen Charakter-Array. Wichtig ist, zu beachten, dass Variablen vom Typ String Referenzvariablen sind. Sie verweisen auf ein Objekt, dass mit Hilfe des new-Operators auf dem Heap angelegt wird. Das bedeutet, nach den folgenden Anweisungen String name1 = new String("Anja"); String name2 = new String("Herbert"); name2 = name1;

zeigen beide Referenzen name1 und name2 auf die Zeichenkette "Anja". Beim Vergleichen von Strings muss deshalb ebenfalls aufgepasst werden. Nach den Anweisungen String s1 = new String("Hallo"); String s2 = new String("Hallo");

liefert die Anweisung s1 == s2 den Wert false, da die Referenzvariablen s1 und s2 auf verschiedene Objekte im Speicher zeigen, die zwar den gleichen Inhalt haben aber nicht identisch sind. Die Anweisung s1.equals(s2) liefert jedoch, wie erwartet, den Wert true, da sie die Objekte auf inhaltliche Gleichheit prüft. Im Folgenden sind noch einige Methoden der String-Klasse aufgeführt. Dabei ist zu beachten, dass jede Methode der Klasse String, die eine veränderte Zeichenkette erzeugt, wie z.B. die Methode substring(), eine neue Instanz der Klasse String liefert und nicht die Original-Instanz mit einem geänderten Inhalt. Denn es gilt, String-Instanzen können nach ihrer Initialisierung nicht mehr geändert werden. public int length() Gibt die Anzahl der Zeichen einer Zeichenkette zurück. public boolean equals(Object obj) Vergleicht zwei String-Objekte miteinander und gibt true zurück, falls die String-Objekte den gleichen Inhalt haben.

Page 23: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 23

public String substring(int anfang, int ende)

Schneidet aus dem aufrufenden String-Objekt die Zeichen von der Position anfang bis zur Position ende-1 heraus und gibt den herausgeschnittenen Teil als neues String-Objekt zurück. Man beachte, dass das erste Zeichen den Index 0 hat. Aufgabe 2.1 Erläutern Sie, warum es zu den gegebenen Konsolenausgaben kommt.

public class StringApp { public static void main(String[] args) { String s1 = new String("Test"); String s2 = new String("Test"); String s3 = "Te"; String s4 = "st"; System.out.println("1: " + (s1 == "Test")); System.out.println("2: " + (s1 == s2)); System.out.println("3: " + ((s3+s4) == s1)); System.out.println("4: " + ((s3+s4).equals(s1))); String s5 = s2.substring(1, 3); System.out.println("5: " + s5); System.out.println("6: " + (s2.substring(1, 3) == s5)); System.out.println("7: " + (s2.substring(1, 3).equals(s5))); } }

Auf der Konsole 1: false 2: false 3: false 4: true 5: es 6: false 7: true

Arrays für einfache Datentypen Beispiel, IntArray1 public class IntArray1 { public static void main(String[] args) { int[] anArray; // Step1: Declare the array anArray = new int[10]; // Step2: Allocate storage // Step3: Initialize the array for (int i = 0; i < anArray.length; i++) { anArray[i] = i; System.out.print(anArray[i] + " "); }

Page 24: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 24

System.out.println(); } }

Auf der Konsole 0 1 2 3 4 5 6 7 8 9 Die Länge eines Arrays wird festgelegt, wenn man zur Laufzeit des Programms mit "new" Speicher für das Array anfordert. Danach hat das Array dann eine feste Länge.

Vorsicht: − Die Länge eines Strings erhält man mit "<Name des Strings>.length()". Die Methode

"length()" aus der Klasse "String" wird dann also auf den String angewendet. − Die Anzahl der Arrayelemente wird dagegen mit "<Name des Arrays>.length" (ohne

Klammernpaar!) ermittelt; "length" ist hier keine Methode sondern eine Instanzvariable des jeweiligen Array-Objektes.

Wie in C reicht der zulässige Indexbereich immer von 0 bis "Arraylänge-1", für einen Array der Länge 10 also zum Beispiel von 0 bis 9.

Beispiel, IntArray2

public class IntArray2 {

public static void main(String[] args) {

int[] anArray = {10, 11, 12, 13, 14}; for (int i = 0; i < anArray.length; i++) System.out.print(anArray[i] + " ");

System.out.println(); } }

Auf der Konsole 10 11 12 13 14

Das vorausgehende Beispiel zeigt, wie sich ein Feld initialisieren lässt. Die Feldlänge ent-spricht dann der Anzahl der Werte in der Initialisierungsliste.

Beispiel, Matrix

public class Matrix { static final int ROWS = 4; static final int COLS = 5;

public static void main(String[] args) { double[][] aMatrix = new double[ROWS][COLS];

// or "...; i < ROWS; ..." for (int i = 0; i < aMatrix.length; i++) { // or "...; j < COLS; ..." for (int j = 0; j < aMatrix[i].length; j++) { aMatrix[i][j] = i+j/10.0;

Page 25: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 25

System.out.print(aMatrix[i][j] + " "); } System.out.println(); } } }

Auf der Konsole 0.0 0.1 0.2 0.3 0.4 1.0 1.1 1.2 1.3 1.4 2.0 2.1 2.2 2.3 2.4 3.0 3.1 3.2 3.3 3.4

Man hätte mit der folgenden Anweisung die Matrix bei der Vereinbarung auch unmittelbar initialisieren können.

double[][] aMatrix = {{0.0, 0.1, 0.2, 0.3, 0.4}, {1.0, 1.1, 1.2, 1.3, 1.4}, {2.0, 2.1, 2.2, 2.3, 2.4}, {3.0, 3.1, 3.2, 3.3, 3.4}}; Aufgabe 2.2 public class IntArray { int[] myArray;

IntArray(int dim) { myArray = new int[dim];

for(int i = 0; i < dim; i++) // random() returns a double value with a positive sign, // greater than or equal to 0.0 and less than 1.0 myArray[i] = (int) (100 * Math.random()); } void sortArray() { ... }

public static void main(String[] args) { IntArray tab = new IntArray(8); tab.sortArray(); for (int i = 0; i < tab.myArray.length; i++) System.out.print(tab.myArray[i] + " "); System.out.println(); } }

Beispiel zur Ausgabe 16 19 21 22 22 57 59 85

Vervollständigen Sie die Methode "sortArray" so, dass sie das Feld "myArray" in aufstei-gender Reihenfolge sortiert.

Page 26: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 26

Arrays für Referenzdatentypen Beispiel, StringArray public class StringArray { public static void main(String[] args) { String[] anArray; // Declare the array anArray = new String[3]; // Allocate storage for references // Do something anArray[0] = "String 0"; // Line 1 anArray[1] = "String 1"; // Line 2 anArray[2] = anArray[1]; // Line 3 anArray[1] += " + new substring"; // Line 4 for (int i = 0; i < anArray.length; i++) System.out.println(anArray[i]); } }

Auf der Konsole String 0 String 1 + new substring String 1

Die Anweisung "anArray = new String[3];" fordert Speicherplatz für 3 Referenzen an und nicht etwa für drei Zeichenketten. Die Zuweisungen in "Line 1" bis "Line 3" führen dazu, dass die Referenz (die Anfangsadresse) der jeweiligen Zeichenkette kopiert wird. In "Line 4" wird eine neue Zeichenkette im dynamischen Speicher abgelegt und deren Referenz dann kopiert. Beispiel, Kommandozeilenargumente public class Echo { public static void main (String[] args) { for (int i = 0; i < args.length-1; i++) System.out.print(args[i]+" "); System.out.println(args[args.length-1]); } }

Auf der Konsole java Echo Klaus Waller Hamburg Klaus Waller Hamburg

Page 27: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 27

Beispiel, RefArray

class Circle { double radius; Circle(double r) {radius = r;} double area() {return 3.14159 * radius * radius;} }

public class RefArray { public static void main(String[] args) {

// Declare the array and allocate storage for references Circle[] anArray = new Circle[2];

// Initialize the array with objects of class Circle anArray[0] = new Circle(1.0); anArray[1] = new Circle(2.0); for (int i = 0; i < anArray.length; i++) System.out.println("Area " + anArray[i].area()); } }

Auf der Konsole Area 3.14159 Area 12.56636

Hier wird im ersten Schritt dynamischer Speicher für zwei Referenzen auf "Circle" ange-fordert. Danach werden zwei Instanzen von "Circle" angelegt und ihre Referenzen nach "anArray" kopiert. Aufgabe 2.3 class Point { int x, y; ... } class Rectangle { Point tl; // top left int width, height; ... } class ChessBoard { static final int DIM = 32; // Height and width of squares Rectangle rct[] = new Rectangle[64]; ... } public class Test {

Page 28: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 28

public static void main(String[] args) { Point p = new Point(225, 240); System.out.println(p); Rectangle r = new Rectangle(p, 122, 234); System.out.println(r); ChessBoard chb = new ChessBoard(); System.out.println(chb); System.out.println("Point " + p + " in square " + chb.getRectInd(p)); } }

Auf der Konsole:

x=225 y=240 topleft: x=225 y=240, width=122 height=234 ChessBoard: [0]: topleft: x=0 y=0, width=32 height=32 b)[63]: topleft: x=224 y=224, width=32 height=32 Point x=225 y=240 in square 63

Vervollständigen Sie das Programm so, dass es die angegebenen Daten ausgibt. Insbesondere ist in jeder Klasse eine geeignete toString()-Methode zu programmieren.

2.2 Die Collection ArrayList

Mit der Klasse "ArrayList" (ab JDK 1.2) kann man Referenzen auf Objekte dynamisch in eine Liste einfügen und aus dieser Liste wieder löschen. Die Liste wird bei Bedarf selbsttätig vergrößert.

Beispiel, ListDemo import java.util.*;

public class ListDemo {

static void printList(ArrayList aList) { for(int i = 0; i < aList.size(); i++) // Get size System.out.println(aList.get(i)); // Get object System.out.println("- - - -"); }

public static void main(String[] args) { String str; ArrayList lst1 = new ArrayList();

for(int i = 0; i < 2; i++) lst1.add("Element " + i); // Append lst1.add(0, "First"); // Insert at position lst1.add(lst1.size(), "Last"); printList(lst1);

Page 29: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 29

lst1.remove("Last"); // Remove element lst1.remove(0); // Remove at position lst1.set(1, "Set"); // Replace at position printList(lst1); ArrayList lst2 = new ArrayList(lst1); lst1.remove(0); lst2.addAll(lst1); // Append all printList(lst2); str = (String) lst2.get(1); // get with typecast System.out.println(str); lst2.clear(); // Remove all printList(lst2); } }

Auf der Konsole:

First Element 0 Element 1 Last - - - - Element 0 Set - - - - Element 0 Set Set - - - - Set - - - -

Die Klasse ArrayList gibt es ab Java 5 in einer typsicheren Form. Diese Typsicherheit ist mit Hilfe so genannter Generics implementiert worden. Es handelt sich dabei um Collection-Klassen, in die nicht allgemein Objekte vom Typ Object abgelegt werden können, sondern die durch eine vorhergehende Typisierung sicherstellen, dass nur Objekte eines bestimmten Typs (etwa Integer oder String) in die Liste eingefügt werden können. Der Typ der Elemente wird dabei als Typparameter übergeben, z.B. ArrayList<String>. Im folgenden sind einige Listenoperationen dargestellt: Element Hinzufügen, add() import java.util.ArrayList; import java.util.Arrays; public class ArrayList_Add { public static void main(String args[]) {

Page 30: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 30

ArrayList<String> list = new ArrayList<String>(); list.add("One"); list.add("Two"); list.add("Three"); // for-each-Schleife for(String item : list) { System.out.println(item); } } } Auf der Konsole: One Two Three

Liste Hinzufügen, addAll() import java.util.ArrayList; import java.util.Arrays; public class ArrayList_AddAll { public static void main(String args[]) { ArrayList<String> list = new ArrayList<String>(); list.add("One"); String[] data = { "Two", "Three", "Four", "Five" }; list.addAll(Arrays.asList(data)); for(String item : list) { System.out.println(item); } } } Auf der Konsole: One Two Three Four Five Abrufen von Werten, get() import java.util.ArrayList; import java.util.Arrays;

Page 31: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 31

public class ArrayList_For { public static void main(String args[]) { ArrayList<String> list = new ArrayList<String>(); list.add("One"); list.add("Two"); list.add("Three"); for(int i=0; i<list.size(); i++) { System.out.println(String.format ("Element at Index #%d: \"%s\"", i, list.get(i))); } } } Auf der Konsole: Element at Index #0: "One" Element at Index #1: "Two" Element at Index #2: "Three"

Ersetzen von Werten, set() import java.util.ArrayList; import java.util.Arrays; public class ArrayList_Set { public static void main(String args[]) { String[] data = { "One", "Two", "Three"}; ArrayList<String> list = new ArrayList<String>(Arrays.asList(data)); list.set(0, "Zero"); for(String item : list) { System.out.println(String.format("%s", item)); } } } Auf der Konsole: Zero Two Three

Page 32: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 32

2.3 Kontrollstrukturen Schleifen while (boolean expression) { statement(s) }

Die Bedingung (boolean expression) wird am Schleifenanfang geprüft. Die Anweisungen in der Schleife werden gegebenenfalls nicht ein einziges Mal ausgeführt.

do { statement(s) } while (boolrean expression);

Die Bedingung (boolean expression) wird am Schleifenende geprüft. Die Anweisungen in der Schleife werden immer mindestens ein Mal ausgeführt. for (initialization; boolean expression; increment) { statement(s) }

Die Bedingung (boolean expression) wird am Schleifenanfang geprüft Die Anweisungen in der Schleife werden gegebenenfalls nicht ein einziges Mal ausgeführt.

Bedingte Ausführung und Alternativen if (boolean expression) { statement(s) }

Die Anweisungen (statement(s)) werden nur ausgeführt, wenn die Bedingung wahr ist. if (boolean expression) { statement(s) 1 } else { statement(s) 2 }

Abhängig von der Bedingung werden alternativ nur die ersten Anweisungen (statement(s) 1) oder die zweiten Anweisungen (statement(s) 2) ausgeführt. if (boolean expression 1) { statement(s) 1 } else if (boolean expression 2) { statement(s) 2 } else if (boolean expression 3) { statement(s) 3 } else { statement(s) 4 }

Page 33: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 33

Abhängig von den Bedingungen (logical expression 1 to 3) werden alternativ nur die ersten Anweisungen (statement(s) 1), oder die zweiten Anweisungen (statement(s) 2), usw. aus-geführt. switch (integer expression) { case integer expression 1: statement(s) 1 break; case integer expression 2: statement(s) 2 break; ... ... default: statement(s) break; }

Abhängig vom ganzzahligen Ausdruck (integer expression) wird zum zugehörigen Fall (case) verzweigt. Die Anweisungen werden ab dieser Stelle bis zum "break" ausgeführt. Wenn keiner der Fälle zutrifft, wird der default-Zweig gewählt. Weitere Kontrollanweisungen continue Die Anweisungen unterbricht die innerste Schleife und führt dazu, dass deren Schleifen-bedingung erneut ausgewertet wird. break

Die Anweisung beendet die innerste "switch", "for", "while" oder "do while" Anweisung.

2.4 Operatoren Arithmetische Operatoren Operator Use Description + op1 + op2 Adds op1 and op2 - op1 - op2 Subtracts op2 from op1 * op1 * op2 Multiplies op1 by op2 / op1 / op2 Divides op1 by op2 % op1 % op2 Computes the remainder of dividing op1 by op2 Operator Use Description ++ op++ Increments op by 1; evaluates the value of op

before the increment operation ++ ++op Increments op by 1; evaluates the value of op after

Page 34: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 34

the increment operation -- op-- Decrements op by 1; evaluates the value of op

before the increment operation -- --op Decrements op by 1; evaluates the value of op after

the increment operation

Vergleichsoperatoren Operator Use Returns true if > op1 > op2 op1 is greater than op2 >= op1 >= op2 op1 is greater than or equal to op2 < op1 < op2 op1 is less than op2 <= op1 <= op2 op1 is less than or equal to op2 == op1 == op2 op1 and op2 are equal != op1 != op2 op1 and op2 are not equal

Logische Operatoren Operator Use Returns true if && op1 && op2 op1 and op2 are both true || op1 || op2 either op1 or op2 is true ! !op op is false

Schiebeoperatoren Operator Use Operation >> op1 >> op2 shift bits of op1 right by distance op2 << op1 << op2 shift bits of op1 left by distance op2 >>> op1 >>> op2 shift bits of op1 right by distance op2 (unsigned)

Aufgabe 2.4 public class Shift { public static void main(String[] args) { int val = 0xFFFFFFFF; String hexStr1 = "0x" + Integer.toHexString(val >> 3); String hexStr2 = "0x" + Integer.toHexString(val >>> 3); System.out.println("val >> 3: " + hexStr1); System.out.println("val >>> 3: " + hexStr2); } }

Was gibt das Programm aus?

Page 35: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 35

Bitoperatoren Operator Use Operation & op1 & op2 bitwise AND | op1 | op2 bitwise OR ^ op1 ^ op2 bitwise XOR ~ ~op2 bitwise NOT

Zuweisungsoperatoren Operator Use Equivalent to = op1 = op2 += op1 += op2 op1 = op1 + op2 -= op1 -= op2 op1 = op1 - op2 *= op1 *= op2 op1 = op1 * op2 /= op1 /= op2 op1 = op1 / op2 %= op1 %= op2 op1 = op1 % op2 &= op1 &= op2 op1 = op1 & op2 |= op1 |= op2 op1 = op1 | op2 ^= op1 ^= op2 op1 = op1 ^ op2 <<= op1 <<= op2 op1 = op1 << op2 >>= op1 >>= op2 op1 = op1 >> op2 >>>= op1 >>>= op2 op1 = op1 >>> op2

Weitere Operatoren Operator Use Description ?: op1 ? op2 : op3 If op1 is true, returns op2. Otherwise, returns

op3. [] type [] Declares an array of unknown length, which

contains type elements. [] type[op1] Creates and array with op1 elements. Must be

used with the new operator. [] op1[op2] Accesses the element at op2 index within the

array op1. Indices begin at 0 and extend through the length of the array minus one.

. op1.op2 Is a reference to the op2 member of op1. () op1(params) Declares or calls the method named op1 with

the specified parameters. (type) (type) op1 Casts (converts) op1 to type. An exception

will be thrown if the type of op1 is incompatible with type.

new new op1 Creates a new object or array. op1 is either a call to a constructor, or an array specification.

instanceof op1 instanceof op2 Returns true if op1 is an instance of op2.

Page 36: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 36

Priorität der Operatoren In der folgenden Tabelle sind die Operatoren in der Reihenfolge ihrer Priorität aufgelistet: je höher in der Tabelle ein Operator aufgeführt ist, desto größer ist seine Priorität. Operatoren in derselben Zeile haben die gleiche Priorität. postfix operators [] . (params) expr++ expr-- unary operators ++expr --expr +expr -expr ~ ! creation or cast new (type)expr multiplicative * / % additive + - shift << >> >>> relational < > <= >= instanceof equality == != bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | logical AND && logical OR || conditional ? : assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=

Für Operatoren mit derselben Priorität gelten die folgenden Zusatzregeln: − Wenn binäre Operatoren derselben Priorität mit Ausnahme von Zuweisungsoperatoren in

einem Ausdruck (expression) zu finden sind, wird der Ausdruck von links nach rechts ausgewertet.

− Zuweisungsoperatoren werden von rechts nach links ausgewertet.

2.5 Ausnahmebehandlung (Exception-Handling) Im Beispiel "Exception1" wird die Programmausführung mit einer Fehlermeldung beendet, wenn es zu einer Division durch Null kommt. Beispiel, Exception1 public class Exception1 { public static void main(String[] args) { for(int i = -2; i <= 2; i++) System.out.println("100/" + i + " = " + 100/i); } }

Auf der Konsole 100/-2 = -50 100/-1 = -100 Exception in thread "main" java.lang.ArithmeticException: / by zero at Exception1.main(Exception1.java:5)

Page 37: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 37

In Java gibt es die Möglichkeit, einen Programmabschnitt zu markieren ("try", versuchen), in diesem Programmabschnitt auftretende Laufzeitfehler "abzufangen" ("catch") und auf sie dann geeignet zu reagieren. Beispiel, Exception2 public class Exception2 { public static void main(String[] args) { for(int i = -2; i <= 2; i++) { try { System.out.println("100/" + i + " = " + 100/i); } catch(ArithmeticException e) { System.out.println("100/0 = ???? " + e); } } } }

Auf der Konsole 100/-2 = -50 100/-1 = -100 100/0 = ???? java.lang.ArithmeticException: / by zero 100/1 = 100 100/2 = 50

Wenn es im try-Block zu einer Ausnahmesituation kommt, unterbricht die Laufzeitumgebung die normale Programmausführung. Das Programm wird dann mit den Anweisungen in der catch-Klausel fortgesetzt, die zur jeweiligen Ausnahmesituation passt, im Beispiel also in der catch-Klausel für eine arithmetische Ausnahmesituation (ArithmeticException). Gibt es keine passende catch-Klausel, wird die Fehlerbehandlung von der Laufzeitumgebung übernommen. Java-Programme haben grundsätzlich die Pflicht, den Compiler über möglicherweise auf-tretende Fehler zu informieren. Dabei gilt die sogenannte "catch-or-throw"-Regel. Diese Regel besagt, dass jede Ausnahme entweder mit einer catch-Klausel abgefangen oder mit "throws" weitergegeben werden muss. Das folgende Beispiel zeigt die Vorgehensweise bei der Weitergabe.

Beispiel, Exception3 public class Exception3 { public static void main(String[] args) throws ArithmeticException { for(int i = -2; i <= 2; i++) System.out.println("100/" + i + " = " + 100/i); } }

Auf der Konsole 100/-2 = -50 100/-1 = -100 Exception in thread "main" java.lang.ArithmeticException: / by zero at Exception3.main(Exception3.java:5)

Page 38: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 38

Um den Aufwand durch die Fehlerbehandlung nicht zu groß werden zu lassen, ist es für viele Laufzeitfehler zulässig, auf die explizite Weitergabe mit "throws" zu verzichten. Das Beispiel "Exception1" zeigt, dass arithmetische Ausnahmesituationen zu diesen Laufzeitfehlern gehören.

Treten in dem eigenen Programm Fehler auf, die in dem von Java zu Verfügung gestellten Klassenbaum der Exceptions noch nicht vertreten sind, so muß man eine spezielle, eigene Ausnahmeklasse vereinbaren. Da Exceptions nichts anderes als Klassen sind, leitet man sich für seine Bedürfnisse einfach eine Klasse von der Klasse Exception oder einer Subklasse ab. Dadurch können die Exceptions unterschieden und entsprechend angepasste Fehlermeldungen ausgegeben werden. Das folgende Beispiel zeigt, wie man eine selbst definierte Exception generieren, auswerfen und wieder fangen kann. Beispiel, Ausnahme1 class MyException extends Exception { public MyException() { // Aufruf des Konstruktors der Klasse Exception. // Ihm wird ein String mit dem Fehlertext übergeben. super ("Fehler ist aufgetreten!"); } } public class MyClass { public static void main (String[] args) { // Dieser try-Block ist untypisch, da in ihm nur eine // Exception zu Demonstrationszwecken geworfen wird. try { MyException ex = new MyException(); throw ex; // Anweisungen unterhalb einer throw-Anweisung in einem // try-Block werden nie abgearbeitet. } catch (MyException e) { System.out.println (e.getMessage()); } } }

Auf der Konsole Fehler ist aufgetreten! Zur Erstellung einer eigenen Exception wird in dem Beispiel die Klasse MyException von der Klasse Exception abgeleitet. Im parameterlosen Konstruktor der Klasse MyException wird mit super() der Konstruktor der Klasse Exception

aufgerufen. An den Konstruktor von Exception wird ein String übergeben, der den

Page 39: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 39

Fehlertext enthält. Dieser Fehlertext kann dann im Fehlerfall mit der Methode getMessage() ausgelesen werden. In obigem Beispiel wurde die Exception direkt im Hauptprogramm generiert und ausgeworfen mit dem Befehl throw ex;

Die Exception kann aber auch von einer Methode erzeugt werden, die an irgendeiner Stelle im Hauptprogramm aufgerufen wird. Eine Exception, die eine Methode auslösen kann, muss dabei zwingend in der Deklaration der Methode mit Hilfe der throws-Klausel angegeben werden. Dadurch wird dem Aufrufer signalisiert, welche Ausnahmen von einer Methode ausgelöst bzw. weitergereicht werden. Der Aufrufer muss die geworfene Exception dann auffangen und sinnvoll behandeln. Im nachfolgenden Beispiel, das nur eine kleine Abwandlung gegennüber dem Beispiel "Ausnahme1" darstellt, wird dies verdeutlicht. Beispiel, Ausnahme2 class MyException extends Exception { public MyException() { // Aufruf des Konstruktors der Klasse Exception. // Ihm wird ein String mit dem Fehlertext übergeben. super ("Fehler ist aufgetreten!"); } } public class MyClass { static void method() throws MyException { MyException ex = new MyException(); throw ex; } public static void main (String[] args) { // Dieser try-Block ist untypisch, da in ihm nur eine // Exception zu Demonstrationszwecken geworfen wird. try { method(); // Anweisungen unterhalb einer throw-Anweisung in einem // try-Block werden nie abgearbeitet. } catch (MyException e) { System.out.println (e.getMessage()); } } }

Page 40: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 40

2.6 Einfache Ein- und Ausgabe

Beispiel, DisplayNumbers1 public class DisplayNumbers1 { public static void main(String[] args) { int iVar1 = 11, int iVar2 = 1/2; double dVar1 = 2.718, double dVar2 = 1.0/3.0; System.out.println("iVar1: " + iVar1); System.out.println("iVar2: " + iVar2); System.out.println("dVar1: " + dVar1); System.out.println("dVar2: " + dVar2); } }

Auf der Konsole iVar1: 11 iVar2: 0 dVar1: 2.718 dVar2: 0.3333333333333333

Im nächsten Beispiel wird die Ausgabe mit Hilfe der statischen Methode "printf()" formatiert: public PrintStream printf(String format, Object... args)

Wobei der Formatstring den Aufbau hat: % [Argument-Index$][Flags][Width][.Precision]Conversion

"Conversion" gibt den Datentyp an. Die wichtigsten Möglichkeiten sind: b - Boolescher Wert c - Einzelnes Zeichen d - Ganzzahl in Dezimaldarstellung o - Ganzzahl in Oktaldarstellung x - Ganzzahl in Hexadezimaldarstellung X - Dito, mit großen Buchstaben f - Flieskommazahl e - Flieskommazahl mit Exponent E - Dito, mit großem "E" g - Flieskommazahl in gemischter Schreibweise G - Dito, ggfs. mit großem "E" t - Prefix für Datums-/Zeitangaben s - Strings und andere Objekte Anders als in C/C++ müssen die Argumente strikt typkonform übergeben werden, was mitunter etwas lästig sein kann. Das Konvertierungszeichen "f" akzeptiert beispielsweise nur Fliesskommazahlen, nicht aber Ganzzahlen; bei "d" ist es genau umgekehrt.

Page 41: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 41

Einen Sonderstatus haben "%" und "n", die für das Prozentzeichen bzw. die Zeilenschaltung stehen und kein zusätzliches Argument benötigen. Mit den "Flags" können weitere Ausgabeoptionen abgerufen werden.

- - Linksbündige Ausgabe + - Vorzeichen immer ausgegeben 0 Zahlen werden mit Nullen aufgefüllt , - Zahlen werden mit Tausenderpunkten ausgegeben ( - Negative Zahlen werden in Klammern eingeschlossen

Sollen mit Hilfe des Konvertierungsprefixes "t" Datums-/Zeitwerte ausgegeben werden, so muß mit einem zweiten Buchstaben direkt dahinter angegeben werden, welcher Teil des Date- oder Calendar-Objektes ausgegeben werden soll. Einige der vielen Möglichkeiten sind: H - Stunde, zweistellig, im 24-Stunden-Format M - Minute, zweistellig S - Sekunde, zweistellig d - Tag, zweistellig m - Monat, zweistellig, 1..12 Y - Jahr, vierstellig F - Datum, formatiert nach ISO 8601 (YYYY-MM-DD) c - Kompletter Datums-/Zeitstring inkl. Zeitzone Beispiel, MyPrintf1 import java.util.*; public class MyPrintf1 { public static void main(String[] args) { //Boolesche Werte System.out.printf("%b %b %2$b %1$b%n", true, false); //Ganzzahlen System.out.printf("[%d]%n", -2517); System.out.printf("[%7d]%n", -2517); System.out.printf("[%-7d]%n", -2517); System.out.printf("[%(7d]%n", -2517); System.out.printf("[%07d]%n", -2517); System.out.printf("[%,7d]%n", -2517); System.out.printf("%1$d %<o %<x %<X%n", 127); //Fliesskommazahlen System.out.printf("%f%n", 0.000314); System.out.printf("%1$6.2f %1$6.2e %1$6.2E %1$6.2G%n", 3.141592); System.out.printf("%,8.2f%n", 31415.92); System.out.printf(Locale.ENGLISH, "%,8.2f%n", 31415.92); //Zeichen und Strings

Page 42: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 42

System.out.printf("%c%c%c\n", 97, 64, 98); System.out.printf("%s nein\n", "ja"); //Datum/Uhrzeit Calendar now = Calendar.getInstance(); System.out.printf( "%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS%n", now ); System.out.printf("%tF%n", now); System.out.printf("%tc%n", now); } }

Auf der Konsole:

true false false true [-2517] [ -2517] [-2517 ] [ (2517)] [-002517] [ -2.517] 127 177 7f 7F 0,000314 3,14 3.14e+00 3.14E+00 3.1 31.415,92 31,415.92 a@b ja nein 26.02.2008 12:28:51 2008-02-26 Di Feb 26 12:28:51 CET 2008

Die Trennzeichen "," und "." entsprechen der deutschen Standardeinstellung (default locale). Aufgabe 2.5

Schreiben Sie ein Programm, das die folgende Tabelle der ASCII-Zeichen 32 bis 127 ausgibt. 32 0x20 33 0x21 ! 34 0x22 " 35 0x23 # 36 0x24 $ 37 0x25 % 38 0x26 & 39 0x27 ' 40 0x28 ( 41 0x29 ) 42 0x2a * 43 0x2b + 44 0x2c , 45 0x2d - 46 0x2e . 47 0x2f / 48 0x30 0 49 0x31 1 50 0x32 2 51 0x33 3 52 0x34 4 53 0x35 5 54 0x36 6 55 0x37 7 56 0x38 8 57 0x39 9 58 0x3a : 59 0x3b ; 60 0x3c < 61 0x3d = 62 0x3e > 63 0x3f ? 64 0x40 @ 65 0x41 A 66 0x42 B 67 0x43 C 68 0x44 D 69 0x45 E 70 0x46 F 71 0x47 G 72 0x48 H 73 0x49 I 74 0x4a J 75 0x4b K 76 0x4c L 77 0x4d M 78 0x4e N 79 0x4f O 80 0x50 P 81 0x51 Q 82 0x52 R 83 0x53 S 84 0x54 T 85 0x55 U 86 0x56 V 87 0x57 W 88 0x58 X 89 0x59 Y 90 0x5a Z 91 0x5b [ 92 0x5c \ 93 0x5d ] 94 0x5e ^ 95 0x5f _ 96 0x60 ` 97 0x61 a 98 0x62 b 99 0x63 c 100 0x64 d 101 0x65 e 102 0x66 f 103 0x67 g 104 0x68 h 105 0x69 i 106 0x6a j 107 0x6b k 108 0x6c l 109 0x6d m 110 0x6e n 111 0x6f o 112 0x70 p 113 0x71 q 114 0x72 r 115 0x73 s 116 0x74 t 117 0x75 u 118 0x76 v 119 0x77 w 120 0x78 x 121 0x79 y 122 0x7a z 123 0x7b { 124 0x7c | 125 0x7d } 126 0x7e ~ 127 0x7f

Page 43: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 43

Beispiel, ReadString import java.io.*; public class ReadString { public static void main(String[] args) throws IOException { // BufferedReader reads text from a character-input stream, // buffering characters so as to provide for the efficient // reading of characters, arrays, and lines // An InputStreamReader is a bridge from byte streams to // character streams: It reads bytes and translates them into // characters according to a specified character encoding // System.in: the "standard" input stream BufferedReader din = new BufferedReader( new InputStreamReader(System.in)); System.out.print("String: "); // Read a line of text String str = din.readLine(); System.out.println(str); } }

Auf der Konsole String: Ich bin ein String mit Leerzeichen Ich bin ein String mit Leerzeichen

Wenn die Angabe von "throws IOException" fehlt, bricht der Compiler mit einer Fehler-meldung ab (vgl. Abschnitt 2.4).

Beispiel, ReadInt import java.io.*; public class ReadInt { public static void main(String[] args) throws IOException { BufferedReader din = new BufferedReader( new InputStreamReader(System.in)); System.out.print("anInt: "); // "parseInt" parses the string argument as a signed // decimal integer int anInt = Integer.parseInt(din.readLine()); System.out.println(anInt); } }

Page 44: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 44

Auf der Konsole anInt: -123 -123

Aufgabe 2.6 Schreiben Sie ein Programm, das ein Rechteck auf der Konsole ausgibt. ******

* * * * ****** Breite (width) und Höhe (height) sollen eingelesen werden. Weisen Sie Eingaben zurück, wenn nicht 1 ≤ Breite ≤ 79 und 1 ≤ Höhe ≤ 20 gilt. Beachten Sie auch den Sonderfall Breite = Höhe = 1. Im folgenden Beispiel wird eine Kopie einer Textdatei angelegt. Die Namen der beiden Dateien sind dabei in der Kommandozeile zu übergeben. Beispiel, CopyTextFile import java.io.*; public class CopyTextFile { public static void main(String[] args) throws IOException { // Line separator (Windows "\r\n", Unix "\n", Mac "\r") final String L_SEP = System.getProperty("line.separator"); BufferedReader in; BufferedWriter out; String txt; if(args.length < 2) { System.out.println("Usage: CopyTextFile <inFile> <outFile>"); return; } try { in = new BufferedReader(new FileReader(args[0])); } catch(FileNotFoundException e) { System.out.println("Could not find file " + args[0]); return; } try { out = new BufferedWriter(new FileWriter(args[1])); }

Page 45: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 45

catch(FileNotFoundException e) { System.out.println("Could not create file " + args[1]); return; } while((txt = in.readLine()) != null) // Copy text file out.write(txt + L_SEP); in.close(); out.close(); } }

2.7 Parameterübergabe bei Methoden In Java werden Methodenparameter generell per Wert übergeben. Das heißt, ein formaler Parameter erhält beim Aufruf der Methode eine Kopie des entsprechenden aktuellen Parameters (Übergabe per Wert, call by value). Dies hat aber völlig unterschiedliche Auswirkungen, je nach dem ob der Übergabeparameter von einfachem Datentyp ist oder von Referenztyp, also eine Objekt repräsentiert. Im folgenden Beispiel betrachten wir zunächst den Fall, dass der Übergabeparameter von einfachem Datentyp ist.

Beispiel, Parameter1 /* * Beispiel: Parameter1 */ public class Parameter1 { public static void method1 (int par) { par = 2; } public static void main(String[] args) { int value = 1; System.out.println("Vor dem Methodenaufruf"); System.out.println("value = " + value); method1(value); System.out.println("Nach dem Methodenaufruf"); System.out.println("value = " + value); } }

Auf der Konsole Vor dem Methodenaufruf value = 1 Nach dem Methodenaufruf value = 1

Page 46: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 46

Die Änderungen, welche die Methode methode1() an der Variablen par vornimmt, haben keine Auswirkung auf den aktuellen Übergabeparameter value. Dies entspricht genau einem call by value. Im nächsten Beispiel ist der Übergabeparameter vom Referenztyp. Auch hier geschieht die Übergabe des Parameters per call by value, diesmal aber wird eine Referenz kopiert. Damit referenziert der formale Parameter par dasselbe Objekt wie der aktuelle Parameter ref. Beide greifen also auf dasselbe Objekt zu. Damit kann das Originalobjekt aber in der Methode verändert werden. Dieses entspricht vom Verhalten her einem call by reference.

Beispiel, Parameter2 /* * Beispiel: Parameter2 */ class RefTyp { int x; } public class Parameter2 { public static void method2 (RefTyp par) { par.x = 2; } public static void main(String[] args) { RefTyp ref = new RefTyp(); ref.x = 1; System.out.println("Vor dem Methodenaufruf"); System.out.println("ref.x = " + ref.x); method2(ref); System.out.println("Nach dem Methodenaufruf"); System.out.println("ref.x = " + ref.x); } }

Auf der Konsole Vor dem Methodenaufruf ref.x = 1 Nach dem Methodenaufruf ref.x = 2

2.8 Zuweisung von Objekten Beim Zuweisen von Objekten muss man Vorsicht walten lassen. Im folgenden Beispiel werden mit der Zuweisung m2 = m1 lediglich die Referenzen kopiert. Man erhält dadurch zwei Referenzen, die auf das gleiche Objekt verweisen. Eine Änderung an der Kopie m2 bewirkt dann auch eine Änderung am Original m1, was in der Regel unerwünscht ist.

Page 47: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 47

Beispiel, MyCopy1 /* * Beispiel: MyCopy1 */ class Mitarbeiter { private String name; private int gehalt; public Mitarbeiter() { } public Mitarbeiter(String name, int gehalt) { this.name = name; this.gehalt = gehalt; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getGehalt() { return gehalt; } public void setGehalt(int gehalt) { this.gehalt = gehalt; } } public class MyCopy1 { public static void main(String[] args) { Mitarbeiter m1 = new Mitarbeiter("Mueller", 2000); Mitarbeiter m2; m2 = m1; // flache Kopie (shallow copy)!!! m2.setName("Schulze"); m2.setGehalt(1500); System.out.println("m2.name = " + m2.getName() + ", m2.gehalt = " + m2.getGehalt()); System.out.println("m1.name = " + m1.getName() + ", m1.gehalt = " + m1.getGehalt()); } }

Page 48: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 48

Auf der Konsole m2.name = Schulze, m2.gehalt = 1500 m1.name = Schulze, m1.gehalt = 1500

Um wirklich eine echte Kopie der Originalobjektes zu erhalten, wird im folgenden Beispiel der Klasse Mitarbeiter die Methode "copy()" hinzugefügt, die ein neues Objekt vom Typ Mitarbeiter erzeugt und alle Daten des Originalobjekts kopiert. Hier werden also alle Daten des Originalobjektes kopiert und nicht nur die Objektvariable, die lediglich eine Referenz auf das Objekt enthält. Beispiel, MyCopy2 /* * Beispiel: MyCopy2 */ class Mitarbeiter { private String name; private int gehalt; public Mitarbeiter() { } public Mitarbeiter(String name, int gehalt) { this.name = name; this.gehalt = gehalt; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getGehalt() { return gehalt; } public void setGehalt(int gehalt) { this.gehalt = gehalt; } public Mitarbeiter copy() { Mitarbeiter c = new Mitarbeiter(); c.name = this.name; c.gehalt = this.gehalt; return c; } }

Page 49: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 49

public class MyCopy2 { public static void main(String[] args) { Mitarbeiter m1 = new Mitarbeiter("Mueller", 2000); Mitarbeiter m2; m2 = m1.copy(); // tiefe Kopie (deep copy)!!! m2.setName("Schulze"); m2.setGehalt(1500); System.out.println("m2.name = " + m2.getName() + ", m2.gehalt = " + m2.getGehalt()); System.out.println("m1.name = " + m1.getName() + ", m1.gehalt = " + m1.getGehalt()); } }

Auf der Konsole m2.name = Schulze, m2.gehalt = 1500 m1.name = Mueller, m1.gehalt = 2000

Wenn in das zu kopierende Objekt wiederum Referenzvariablen eingebettet sind, unter-scheidet man erneut zwischen flacher and tiefer Kopie. − Flache Kopie (shallow copy): Man kopiert die eingebetteten Referenzvariablen. An-

schließend verweisen dann also die eingebetteten Referenzvariablen von Original und Kopie auf ein- und dieselben Daten.

− Tiefe Kopie (deep copy): Man kopiert auch die Daten, auf die die eingebetteten Referenz-variablen verweisen.

In einem späteren Kapitel werden wir sehen, dass man für das kopieren von Objekten in der Regel die Methode clone() verwendet, die in der Basisklasse Object, von der alle Klassen abgeleitet sind, vordefiniert ist. Man muss dazu das Interface Cloneable implementieren und die Methode clone() in der eigenen Klasse überschreiben.

2.9 Vergleich von Objekten

Auch beim Vergleichen von Objekten, also Referenzvariablen, muss man ähnlich Vorsicht walten lassen wie bei der Zuweisung von Objekten. Bei Referenztypen wird mit dem Vergleich a == b getestet, ob die Referenzen gleich sind, das heißt, es wird getestet, ob die Referenzvariablen auf dieselbe Instanz verweisen. Es wird aber nicht geprüft, ob zwei unterschiedliche Instanzen den gleichen Inhalt haben. Will man diesen Test auf inhaltliche Gleichheit bei unterschiedlichen Instanzen haben, so muss in der eigenen Klasse die Methode equals(), die von der Klasse Object geerbt wird, überschrieben werden. Wir hatten dieses Problem bei Zeichenketten (Strings) schon einmal angesprochen. In der Klasse String gibt es bereits eine geeignete Methode equals(), die zwei verschiedene Strings auf Gleichheit prüft. Im folgenden Beispiel wird das noch einmal an Hand einer eigenen Klasse dargestellt. Dort ist die Klasse Book entworfen, um z.B. Bücher einer Bibliothek zu erfassen. Der Klasse Book wurde eine geeignete Methode equals() hinzugefügt, die zwei verschiedene Objekte der Klasse Book als gleich erkennt, wenn Titel und Autor identisch sind.

Page 50: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 50

/* * Beispiel: Vergleich1 */ class Book { private String title; private String author; public Book(String title, String author) { this.title = title; this.author = author; } public boolean equals(Object otherObject) { // true, wenn die Objekte identisch sind if (this == otherObject) return true; // false, wenn otherObject == null if (otherObject == null) return false; // false, wenn die Klassen nicht gleich sind if (getClass() != otherObject.getClass()) return false; Book other = (Book) otherObject; // true, wenn title und author gleich return title.equals(other.title) && author.equals(other.author); } } public class Vergleich1 { public static void main(String[] args) { Book b1 = new Book("Java 6", "Samaschke"); Book b2 = new Book("Java 6", "Samaschke"); System.out.println(b1 == b2); System.out.println(b2.equals(b1)); } }

Auf der Konsole false true

Page 51: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 51

2.10 Übungsaufgaben

Übungsaufgabe 2.1 Schreiben Sie ein Programm, das eine Zeichenkette (String) einliest und diese Zeichenkette dann in umgekehrter Reihenfolge wieder ausgibt. Beispiel String: Heute ist Montag gatnoM tsi etueH

Hinweis: Im Anhang ist eine Kurzbeschreibung der Methoden der Klasse "java.lang.String" zu finden.

Übungsaufgabe 2.2 Schreiben Sie ein Programm zur grafischen Ausgabe der folgenden Funktion:

432 xexdxcxbay ⋅+⋅+⋅+⋅+=

Das untenstehende Beispiel zeigt, wie die Parameter eingegeben werden sollen und wie die Grafik auszugeben ist. Die Grafik besteht aus 17 Zeilen und 71 Spalten und soll so beschriftet werden, wie es das Beispiel zeigt.

Auf der Konsole Geben Sie die Parameter ein: a: -2 b: -2 c: 0 d: 1 e: .1 4| y | * | * | | * | * | * | * x ----------------------------------------------------------------*------ -2 0| * 2 *************** | ** *** ***** | * *** ***** ** ** | ***** *** * | ************ ** | * -4|

Page 52: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

2 Grundelemente von Java 52

Übungsaufgabe 2.3 Vervollständigen Sie die Klasse "IntStack" für Daten vom Typ "int" so, dass sich "main" ausführen lässt und die gegebene Konsolenausgabe liefert. class IntStack { int stack[], stackSize, index; ... ... } public class Test { public static void main(String[] args) { IntStack stack1 = new IntStack(2); stack1.push(2); stack1.push(5); stack1.push(1); // Stack ist voll while(!stack1.empty()) System.out.println("Stack 1: " + stack1.pop()); stack1.pop(); // Stack ist leer IntStack stack2 = new IntStack(3); stack2.push(-3); stack2.push(44); stack2.push(-9); while(!stack2.empty()) System.out.println("Stack 2: " + stack2.pop()); } }

Auf der Konsole Stack ist voll! Stack 1: 5 Stack 1: 2 Stack ist leer! Stack 2: -9 Stack 2: 44 Stack 2: -3

Page 53: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung

Aus Abschnitt 1.2 sind die folgenden Begriffe schon bekannt: − Klassen und Objekte; − Instanz- und Klassenvariablen (static), sowie Konstanten (static final); − Konstruktor, Standardkonstruktor, Methoden und Überladen von Methoden; − Instanz- und Klassenmethoden (static), − die Referenz "this".

3.1 Das Konzept der Vererbung

Eine Klasse kann ihre Daten und Methoden an eine andere Klasse "vererben" (Bild 3.1)

Transportmittel

Landtransportmittel

"ist ein"-Beziehung

Oberklasse (superclass)

Abgeleitete Klasse(subclass)

Bild 3.1 Oberklasse und abgeleitete Klasse

Die vererbende Klasse wird Oberklasse (superclass) genannt, die erbende Klasse bezeichnet man als abgeleitete Klasse (subclass). Es ist üblich, dass der Vererbung eine "ist ein"-Beziehung zugrunde liegt: ein Landtransportmittel ist ein Transportmittel. Wenn man den Pfeil in diesem Sinn liest, ist seine Richtung sinnvoll.

Die Vererbung ist nicht auf zwei Klassen beschränkt. Bild 3.2 zeigt ein umfangreicheres Beispiel. − Die Klasse "Transportmittel" enthält Daten und Methoden, die allen Transportmitteln

gemeinsam sind. − Von dieser Klasse wird "Landtransportmittel" abgeleitet, und es werden die für diese

Teilmenge der Transportmittel notwendigen Daten und Methoden hinzugefügt. − Ein "Auto" ist ein "Landtransportmittel". Die Klasse "Landtransportmittel" stellt also aus

Sicht der Klasse "Auto" die Oberklasse dar. − Die Klasse "Amphibienfahrzeug" erbt Daten und Methoden von "Auto" und von

"Wassertransportmittel". Ein Amphibienfahrzeug ist ein Auto, und ein Amphibien-fahrzeug ist ein Wassertransportmittel. In Java ist Mehrfachvererbung nicht zulässig.

Eine Oberklasse stellt eine Generalisierung der von ihr abgeleiteten Klassen dar. "Landtrans-portmittel" enthält z.B. für "Rikscha", "Fahrrad" und "Auto" gemeinsame Daten und Methoden. Jede abgeleitete Klasse fügt dann für sie typische Dinge hinzu oder legt das geerbte Verhalten neu fest.

Eine abgeleitete Klasse ist eine Spezialisierung ihrer Oberklasse. "Rikscha", "Fahrrad" und "Auto" sind z.B. spezielle "Landfahrzeuge". In der jeweiligen Klasse brauchen nur noch die Abweichungen beschrieben zu werden, alles andere kann man wiederverwenden.

Page 54: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 54

Transportmittel

breite hoehe

bewegen()

Landtransportmittel

radzahl

fahren() schieben()

Wassertransportmittel

bruttoregistertonnen

anlegen() ablegen()

Auto

spritverbrauch

starten() fahren() tanken()

Fahrrad

...

...

Amphibienfahrzeug

hersteller

schottenDichtmachen()

Klasse

Daten

Methoden

Rikscha

...

...

Bild 3.2 Beispiel zur Vererbung von Daten und Methoden Im Programmcode kennzeichnet man die Vererbung in der Kopfzeile der abgeleiteten Klasse. class Transportmittel { double breite, hoehe; void bewegen() {...} } class Landtransportmittel extends Transportmittel { int radzahl; void fahren() {...} void schieben() {...} } class Auto extends Landtransportmittel { double spritverbrauch; void starten() {...} void fahren() {...} void schieben() {...} } ... ... ...

Page 55: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 55

Im folgenden Programmausschnitt wird als Beispiel ein Objekt "auto" vom Typ "Auto" vereinbart.

public static void main(String[] args) { Auto auto = new Auto(); ... }

Bild 3.3 veranschaulicht, dass "auto" je ein Objekt der Klassen "Landtransportmittel" und "Transportmittel" enthält. In ein Objekt einer abgeleiteten Klasse ist also je ein anonymes Objekt seiner Oberklasse(n) eingebettet. Zu "auto" gehören folglich die Daten "breite", "hoehe", "radzahl" und "spritverbrauch", sowie die Methoden "bewegen()", "fahren()", "schieben()", "starten()", "fahren()" und "tanken()".

Transportmittel

breite hoehe

bewegen()

Landtransportmittel

radzahl

fahren() schieben()

Auto

spritverbrauch

starten() fahren() tanken()

Bild 3.3 Ein Objekt der Klasse "Auto" enthält je ein Objekt der Klassen "Landtransportmittel" und "Transportmittel"

Aufgabe 3.1 Warum lässt der Compiler die Zuweisung 1 zu, meldet dann aber für die Zuweisung 2 einen Fehler? ... ... (Programmcode zu Bild 3.3) ... public class Test { public static void main(String[] args) { Landtransportmittel ltm = new Landtransportmittel(); Auto auto = new Auto(); ltm = auto; // Zuweisung 1 auto = ltm; // Zuweisung 2 } }

Page 56: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 56

Ein Beispiel Ein Unternehmen hat unterschiedliche Mitarbeiter: Arbeiter, Vertreter, Manager, usw. Die Mitarbeiter unterscheiden sich z.B. in der Art, in der ihr Monatsgehalt berechnet wird. • Arbeiter: Stundenlohn * Stunden, • Vertreter: Stundenlohn * Stunden + Provision * Anzahl, • Manager: Festes Gehalt, • usw. Für die Mitarbeiter sind Namen und gehaltsrelevante Daten zu speichern und die Namen und das zugehörige Gehalt sind auszugeben. In einem ersten Programm wird für jeden Mitarbeitertyp eine eigene Klasse mit allen benötigten Daten vereinbart. Wir nutzen hier nicht das Konzept der Vererbung. Beispiel, Employee1 class Worker //Arbeiter { String name; // Name double hourlyWage; // Stundenlohn double hours; // Stunden Worker(String n, double hW, double h) { name = new String(n); hourlyWage = hW; hours = h; } void display() { System.out.println(name + " " + hourlyWage * hours + " EUR"); } } class SalesAgent //Vertreter { String name; // Name double hourlyWage; // Stundenlohn double hours; // Stunden double commission; // Provision double count; // Anzahl SalesAgent(String n, double hW, double h, double c, double cn) { name = new String(n); hourlyWage = hW; hours = h; commission = c; count = cn; } void display() { System.out.println(name + " " + (hourlyWage * hours + commission * count)

Page 57: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 57

+ " EUR"); } } class Manager // Manager { String name; // Name double salary; // Gehalt; Manager(String n, double s) { name = new String(n); salary = s; } void display() { System.out.println(name + " " + salary + " EUR"); } } public class Employee1 { public static void main(String[] args) { Worker w = new Worker("Meyer, Klaus", 15.82, 151.00); SalesAgent s = new SalesAgent("Hamer, Peter", 8.80, 150.0, 60.28, 22.0); Manager m = new Manager("Kramer, Hans", 3501.27); w.display(); s.display(); m.display(); } }

Auf der Konsole Meyer, Klaus 2388.82 EUR Hamer, Peter 2646.16 EUR Kramer, Hans 3501.27 EUR

Es liegt hier nah, zur Lösung eine Klassenhierarchie einzusetzen. Ein entscheidender Vorteil liegt darin, dass bestehender Code wieder verwendet werden kann. Bereits bestehende Konstruktoren und Methoden der Superklassen können wieder verwendet werden. Dort durchgeführte Sicherheitsprüfungen und Plausibilitätschecks werden übernommen, und so können robuste Programme geschrieben werden. Das Beispiel "Employee2" zeigt die Vorgehensweise. Es wir dieselbe Aufgabenstellung programmiert wie in Beispiel "Employee1" aber diesmal unter Verwendung von Vererbung. Von der Basisklasse Employee wird die Klasse Worker abgeleitet und von dieser wiederum die Klasse SalesAgent. Von der Klasse Employee wird außerdem die Klasse Manager abgeleitet (Bild 3.4). Mit "super(..)" kann in einer Klasse jeweils der Konstruktor der Oberklasse, der "Vatersklasse", aufgerufen werden. Dadurch ergibt sich in Klassenhierarchien eine Verkettung der Konstruktoren. Methoden einer Superklasse, wie im nachfolgenden Beispiel die Methode display() der Klasse Worker, können in einer Subklasse überschrieben werden. Beim Überschreiben einer

Page 58: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 58

Methode müssen aber die Signatur und der Rückgabewert der überschreibenden Methode identische sein mit der Signatur und dem Rückgabewert der überschriebenen Methode.

Employee

Worker Manager

SalesAgent

Bild 3.4 Klassenhierarchie

Beispiel, Employee2 class Employee { String name; // Name Employee(String n) { name = new String(n); } void displayName() { System.out.print(name + " " ); } } class Worker extends Employee { double hourlyWage; // Stundenlohn double hours; // Stunden Worker(String n, double hW, double h) { super(n); hourlyWage = hW; hours = h; } double workerSalary() { return hourlyWage * hours; } void display() { displayName(); System.out.println(workerSalary() + " EUR"); } }

Page 59: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 59

class SalesAgent extends Worker { double commission; // Provision double count; // Anzahl SalesAgent(String n, double hW, double h, double c, double cn) { super(n, hW, h); commission = c; count = cn; } void display() { displayName(); System.out.println((workerSalary() + commission*count) + " EUR"); } } class Manager extends Employee { double salary; // Gehalt Manager(String n, double s) { super(n); salary = s; } void display() { displayName(); System.out.println(salary + " EUR"); } } public class Employee2 { public static void main(String[] args) { Worker w = new Worker("Meyer, Klaus", 15.82, 151.00); SalesAgent s = new SalesAgent("Hamer, Peter", 8.80, 150.0, 60.28, 22.0); Manager m = new Manager("Kramer, Hans", 3501.27); w.display(); s.display(); m.display(); } } Auf der Konsole Meyer, Klaus 2388.82 EUR Hamer, Peter 2646.16 EUR Kramer, Hans 3501.27 EUR

Page 60: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 60

Mit "super(..)" wird jeweils der Konstruktor der Oberklasse, des "Vatersklasse", aufgerufen. Unmittelbare Zugriffe auf den Konstruktor der "Großvaterklasse" sind in Java nicht möglich In "SalesAgent" ist also z.B. kein Zugriff auf den Konstruktor von "Employee" durchführbar. (Anweisungen wie "super.super(..)" sind nicht zulässig.)

Hinweis: Wenn ein Konstruktor die Anweisung "super(...)" enthält, muss sie die erste Anweisung dieses Konstruktors sein! Aufgabe 3.2 Im Beispiel "Empoyee2" wird in der Klasse "Employee" die Methode "displayName()" in "display()" umbenannt. class Employee { String name; Employee(String n) { name = new String(n); } void display() { System.out.print(name + " " ); } }

Erläutern Sie dadurch verursachte Programmänderungen und die dadurch entstehenden Probleme. Im nachfolgenden Programmbeispiel "Employee3" wird der Konstruktor der Oberklasse "Employee" nicht mehr explizit mit "super(...)" aufgerufen. Die Konsolenausgabe zeigt, dass der Compiler dann selbständig einen Aufruf des Standardkonstruktors der Oberklasse generiert. Beispiel, Employee3 class Employee { String name; Employee() { System.out.println("--- Employee-Konstruktor ---" ); } void displayName() { System.out.print(name + " " ); } } class Worker extends Employee { double hourlyWage; double hours; Worker(String n, double hW, double h) { name = new String(n); hourlyWage = hW; hours = h; }

Page 61: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 61

double workerSalary() { return hourlyWage * hours; } void display() { displayName(); System.out.println(workerSalary() + " EUR"); } } public class Employee3 { public static void main(String[] args) { Worker w = new Worker("Meyer, Klaus", 15.82, 151.00); w.display(); } }

Auf der Konsole --- Employee-Konstruktor --- Meyer, Klaus 2388.82 EUR

Hinweis: Wenn der Compiler im Konstruktor einer abgeleiteten Klasse als erste Anweisung kein "super(..)" findet, erzeugt er selbständig einen Aufruf des Standardkonstruktors der Oberklasse2.

Aufgabe 3.3

Im Beispiel "Empoyee3" wird in der Klasse "Employee" der Standardkonstruktor aus-kommentiert. class Employee { ... // Employee() { System.out.println("Employee-Konstruktor" ); } ...

Kommt es dann zu einer Fehlermeldung des Compilers? Im nachfolgenden Beispiel werden noch einmal das Überschreiben von Methoden und das Verdecken von Membervariablen in einer Vererbungshierarchie dargestellt. Die überschriebene Instanzmethode methode() einer Vaterklasse kann mit super.methode() innerhalb von Instanzmethoden der abgeleiteten Sohnklasse angesprochen werden. Der Aufruf super.methode() wird dabei vom Compiler in ((Vaterklasse) this).methode() umgesetzt. Vom Verdecken einer Membervariable spricht man, wenn es in der Sohnklasse eine Membervariable mit gleichem Namen gibt, wie in der Vaterklasse. Der Zugriff auf eine von der Vaterklasse ererbte, verdeckte Instanzvariable x erfolgt mit super.x. Der Zugriff super.x wird dabei vom Compiler in den Zugriff ((Vaterklasse) this).x umgesetzt.

2 Es gibt eine Ausnahme zu dieser Regel, wenn ein Konstruktor einer Klasse einen anderen Konstruktor derselben Klasse aufruft ([2], [3]).

Page 62: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 62

Beispiel, Ueberschreiben //------------------------------------------------------------- class A { char c = 'A'; void f1() {System.out.println("f1 aus " + c);} void f2() {System.out.println("f2 aus " + c);} void f3() {System.out.println("f3 aus " + c);} } //------------------------------------------------------------- class B extends A { char c = 'B'; void f1() {System.out.println("f1 aus " + c + " extends " + super.c);} void f2() {System.out.println("f2 aus " + c + " extends " + super.c);} } //------------------------------------------------------------- class C extends B { char c = 'C'; void f1() { System.out.println("f1 aus " + c + " extends " + super.c); super.f1(); super.f2(); super.f3(); } } //------------------------------------------------------------- public class SuperDemo { public static void main(String[] args) { A a = new A(); a.f1(); a.f2(); a.f3(); B b = new B(); b.f1(); b.f2(); b.f3(); C c = new C(); c.f1(); c.f2(); c.f3(); } }

Page 63: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 63

Auf der Konsole f1 aus A f2 aus A f3 aus A f1 aus B extends A f2 aus B extends A f3 aus A f1 aus C extends B f1 aus B extends A f2 aus B extends A f3 aus A f2 aus B extends A f3 aus A

3.2 Die Basisklasse Object In Java besitzt jede selbstdefinierte Klasse eine Superklasse. Wenn man diese Superklasse nicht mit "extends" angibt, dann wird automatisch die Klasse "Object" zur Superklasse (Bild 3.5).

Employee

Worker Manager

SalesAgent

Object

Bild 3.5 Klassenhierarchie zum Beispiel "Employee2" mit Superklasse Object

Die Klasse "Object" − ist die einzige Klasse, die keine Superklasse besitzt und − ihre Methoden können in jedem Javaobjekt aufgerufen werden. Im folgenden Beispiel werden die drei Methoden "toString", "hashCode" und "equals" ein-gesetzt, die von "Object" geerbt worden sind. Eine weitere Methode ("clone") folgt in einem späteren Abschnitt.

Beispiel, Object1 package consolepack;

class Employee { // extends Object String name; Employee(String n) { name = new String(n); } }

Page 64: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 64

public class Object1 { public static void main(String[] args) { Employee e1 = new Employee("Meyer, Klaus"); Employee e2 = new Employee("Meyer, Klaus");

System.out.println(e1.toString()); System.out.println(e2); System.out.println(Integer.toHexString(e1.hashCode())); System.out.println(Integer.toHexString(e2.hashCode()));

System.out.println(e1.equals(e2)); System.out.println(e1 == e2); } }

Auf der Konsole consolepack.Employee@1cde100 consolepack.Employee@16f0472 1cde100 16f0472 false false

Die Methode "hashCode" berechnet einen numerischen Wert, der als Schlüssel zur Speiche-rung eines Objekts in einer Hash Tabelle eingesetzt werden kann. Weitergehende Informa-tionen sind z.B. in [2] zu finden. Im folgenden Beispiel werden die geerbten Methoden "toString" und "equals" durch eigene Methoden ersetzt ("überschrieben").

Beispiel, Object2

class Employee { // extends Object String name; Employee(String n) { name = new String(n); } public String toString() { return name; } public boolean equals(Object obj) { return name.equals(((Employee) obj).name); } }

public class Object2 { public static void main(String[] args) { Employee e1 = new Employee("Meyer, Klaus"); Employee e2 = new Employee("Meyer, Klaus");

System.out.println(e1.toString()); System.out.println(e2); System.out.println(e1.equals(e2)); System.out.println(e1 == e2); } }

Page 65: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 65

Auf der Konsole Meyer, Klaus Meyer, Klaus true false

Ein anderes Beispiel für das Überschreiben der equals()-Methode hatten wir bereits in dem Kapitel 2.9 gesehen. Dort war die equals()-Methode in geeigneter Weise für die Klasse Book überschrieben worden. In der Klasse String ist bereits eine geeignete equals()-Methode implementiert, die zwei Zeichenketten Buchstaben für Buchstaben auf inhaltliche Gleichheit prüft.

3.3 Typkonvertierung in Vererbungshierarchien Wir betrachten die folgende Klassenhierarchie bestehend aus der Vaterklasse Vater und der davon abgeleiteten Sohnklasse Sohn. class Vater { int valueVater; public void methodVater() {...} } class Sohn extends Vater { int valueSohn; public void methodSohn() {...} }

Wir betrachten eine Zuweisung, bei der eine Referenzvariable vom Typ der Sohnklasse einer Referenzvariablen vom Typ der Vaterklasse zugewiesen wird. Sohn refSohn = new Sohn(); Vater refVater = refSohn; Die Referenzvariable refVater vom Typ Vater zeigt damit auf ein Objekt der Klasse Sohn. Dies ist zulässig, weil ein Sohnobjekt durch den Vererbungsmechanismus auch alle Eigenschaften eines Vaterobjektes besitzt. Bei der Zuweisung findet eine implizite Typkonvertierung auf den Typ Vater statt mittels des cast-Operators (Vater) angewandt auf die Referenz refSohn. Allerdings sieht die Referenz refVater vom Typ Vater nur die Vateranteile des Sohnobjekts, und die Anweisung refVater.methodeSohn() führt natürlich zu einem Compilerfehler, da zur Compile-Zeit unter Umständen ja noch gar nicht feststeht, ob die Referenz refVater auf ein Sohn- oder ein Vaterobjekt zeigt. Eine solche implizite Typkonvertierung in eine Superklasse wird auch als Up-Cast bezeichnet. Die umgekehrte Zuweisung, Vater refVater = new Vater(); Sohn refSohn = refVater;

Page 66: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 66

bei der eine Referenzvariable vom Typ der Vaterklasse einer Referenzvariablen vom Typ der Sohnklasse zugewiesen wird, ist unzulässig und führt zu einem Compilerfehler. Dies ist einleuchtend, weil ein Vaterobjekt nicht alle Eigenschaften eines Sohnobjektes besitzt. Man kann diese Zuweisung erzwingen durch eine explizite Typkonvertierung der Form Sohn refSohn = (Sohn) refVater; Eine solche explizite Typkonvertierung in eine Subklasse wird auch als Down-Cast bezeichnet. Man muss aber beachten, dass die obige Zuweisung nur sinnvoll ist, wenn man vorher sichergestellt hat, dass die Referenzvariable refVater tatsächlich auf ein Sohnobjekt zeigt. Dies kann mit Hilfe des Operators instanceof geschehen, der nachfolgend noch genauer beschrieben wird. Zeigt die Referenz refVater auf ein Objekt der Vaterklasse, so führt obige Typkonvertierung zum Programmabsturz, und zwar wegen einer ClassCastException. Mit dem Operator instanceof kann man ermitteln, zu welcher Klasse ein Objekt gehört. Der Ausdruck "x instanceof y" liefert genau dann "true", wenn "x" eine Instanz der Klasse "y" oder einer von ihr abgeleiteten Klasse ist. Dies kann man nutzen, um obige Zuweisung sicher zu programmieren. Mit dem instanceof-Operator lässt sich prüfen, ob das referenzierte Objekt tatsächlich von dem angenommenen Typ ist. Mit diesem Ergebnis kann die Referenz dann in den entsprechenden Typ down-gecastet werden. if (refVater instanceof Sohn) Sohn refSohn = (Sohn) refVater;

3.4 Verwendung des Operators instanceof

Das Up-casten und das sichere Down-casten mit dem Operator instanceof wird in der Praxis häufig genutzt, wenn in einer Collection oder auch einem Array Objekte aus einer Vererbungshierarchie abgespeichert werden sollen. Die Elemente des Arrays sind dann Referenzen vom Typ der Basisklasse. Diesen Referenzen können auch Instanzen vom Typ der abgeleiteten Klassen zugewiesen werden. Auf diese Weise können Objekte der gesamten Vererbungshierarchie in dem Array abgelegt werden. Mit dem instanceof-Operator kann man nun feststellen, von welchem Klassentyp ein bestimmtes Array Element zur Laufzeit ist, und dann die entsprechenden Methoden aufrufen. Dazu das folgende Beispiel.

Beispiel, OpInstanceof

class Shape { int x, y; Shape(int x, int y) {this.x = x; this.y = y;} }

class Circle extends Shape { int r; Circle(int x, int y, int r) { super(x, y); this.r = r; } }

class Text extends Shape { String s; Text(int x, int y, String s) { super(x, y); this.s = s; } }

Page 67: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 67

class BoldText extends Text { BoldText(int x, int y, String s) { super(x, y, s); } }

//--------------------------------------------------------- public class OpInstanceof { public static void main(String[] args) { Shape shape[] = new Shape[4];

shape[0] = new Shape(10, 20); shape[1] = new Circle(10, 20, 200); shape[2] = new Text(10, 20, "Monday to Friday"); shape[3] = new BoldText(10, 20, "Sunday");

for(int i = 0; i < shape.length; i++) System.out.println(shape[i] instanceof Text);

for(int i = 0; i < shape.length; i++) { if(shape[i] instanceof BoldText) System.out.println("Bold: " + ((BoldText) shape[i]).s); else if(shape[i] instanceof Text) System.out.println(((Text) shape[i]).s); } } }

Auf der Konsole false false true true Monday to Friday Bold: Sunday

3.5 Pakete und Sichtbarkeit Pakete

Pakete (Packages) dienen dazu, die Software eines größeren Projektes in inhaltlich zusammenhängende Bereiche einzuteilen. Jedes Paket entspricht dabei einer Klassen-Bibliothek. Java Klassen, die zu einem Paket gehören, lassen sich dann mit der schon bekannten "import"-Anweisung in ein Programm einbinden. Pakete können aus verschiedenen Quellcode-Dateien bestehen. Jede Quellcode-Datei, die zu einem Paket gehört, muss mit derselben Paketdeklaration beginnen. Alle Programmeinheiten einer Quellcode-Datei gehören auf jeden Fall zum gleichen Paket. Im folgenden Beispiel "PackageDemo" wird die folgende Verzeichnisstruktur benutzt: <Pfad> // Pfad für PackageDemo <Pfad>\demo // Subdirectory mit Klassen A und B <Pfad>\demo\tools // Subdirectory mit Klasse C

Page 68: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 68

Beispiel, PackageDemo (nach [1])

In Datei "<Pfad>\PackageDemo.java" import demo.*; import demo.tools.*; public class PackageDemo { public static void main (String args[]) { A a = new A(); B b = new B(); C c = new C(); a.Hello(); b.Hello(); c.Hello(); } }

In Datei "<Pfad>\demo\A.java" package demo; public class A { public void Hello(){ System.out.println("--- A ---"); } }

In Datei "<Pfad>\demo\B.java" package demo; public class B { public void Hello(){ System.out.println("--- B ---"); } }

In Datei "<Pfad>\demo\tools\C.java" package demo.tools; public class C { public void Hello(){ System.out.println("--- C ---"); } }

Auf der Konsole --- A --- --- B --- --- C ---

Page 69: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 69

Beim Übersetzen von "PackageDemo" prüft der Compiler selbsttätig, ob die ".class"-Dateien in den Packages "demo" und "demo.tools" noch aktuell sind. Andernfalls übersetzt er die zugehörigen Quelldateien erneut. Es wird übersetzt, wenn zu einer ".java"-Datei noch keine ".class"-Datei existiert oder eine ".java"-Datei neuer als die zugehörige ".class"-Datei ist.

− Wenn eine "package"-Anweisung verwendet wird, muss sie die erste Anweisung in der Quelldatei sein.

− Klassen ohne "package"-Anweisung gehören zu einem namenlosen Default-Paket (default package).

Default-Pakete sind für kleinere Programmierprojekte gedacht, für die es sich nicht lohnt, eigene Packages anzulegen. In aller Regel gehören alle in einem Verzeichnis oder in einem Unterverzeichnis gespeicherte Klassen zu ein- und demselben Default-Paket.

Sichtbarkeit Tabelle 3.1 gibt einen Überblick über die Sichtbarkeit von Daten und Methoden. Die Sichtbarkeit lässt sich mit Modifikatoren verändern (private, <default>, protected, public). Tabelle 3.1 Sichtbarkeit von Daten und Methoden

private <default> protected public In der Klasse X X X X In einer abgeleiteten Klasse (X) X Im Paket (package) X X X Überall X

(X) = Mit Einschränkungen.

− Mit "private" vereinbarte Daten und Methoden sind nur in der eigenen Klasse sichtbar. − Ohne Angabe eines Modifikators (<default>) vereinbarte Daten und Methoden sind nur

im eigenen Paket sichtbar. − Mit "protected" vereinbarte Daten und Methoden sind im eigenen Paket und mit Ein-

schränkungen in abgeleiteten Klassen in anderen Paketen sichtbar. − Mit "public" vereinbarte Daten und Methoden sind überall sichtbar.

Im Folgenden wollen wir den Zugriffsschutz von Membervariablen und Methoden mittels Modifikatoren an Hand eines Beispiels noch deutlicher machen. Für die weitere Diskussion gehen wir davon aus, dass sich die Klassen A, B und C im Paket x befinden und die Klassen D und E im Paket y. Die Klasse C im Paket x ist von der Klasse A abgeleitet. Ebenso ist die Klasse E im Paket y von der Klasse A abgeleitet. Die Klasse A im Paket x hat die Membervariable valueInA und die Methode methodInA(). Als Diskussionsgrundlage sollen diese zunächst den Zugriffsschutz "private", dann "<default>", dann "protected" und schließlich "public" haben. Beispiel: ProtectedDemo //--- package x ------------------- package x;

Page 70: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 70

public class A { private int valueInA = 0; private void methodInA() { System.out.println("Method in A"); } } package x; public class B { public void methodInB() { A refA = new A(); refA.valueInA = 5; // z1 refA.methodInA(); // z2 } } package x; public class C extends A { public void methodInC() { valueInA = 2; // z1 methodInA(); // z2 A refA = new A(); refA.valueInA = 5; // z3 refA.methodInA(); // z4 } } // --- package y ------------------- package y; import x.A; public class D { public void methodInD() { A refA = new A(); refA.valueInA = 5; // z1 refA.methodInA(); // z2 } }

package y; import x.A; public class E extends A { public void methodInE() { valueInA = 2; // z1 methodInA(); // z2 A refA = new A(); refA.valueInA = 5; // z3 refA.methodInA(); // z4 } }

Page 71: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 71

Zugriffsmodifikator "private": Haben die Membervariablen und Methoden der Klasse A das Zugriffsrecht "private", so kann aus keiner der Klassen B, C, D und E auf die privaten Membervariablen und Methoden der Klasse A zugegriffen werden.

Zugriffsmodifikator "<default>":

Haben die Membervariablen und Methoden der Klasse A das Zugriffsrecht "<default>", so kann aus Klassen heraus, die im gleichen Paket liegen, zugegriffen werden. Die Zugriffe auf die Variable valueInA und die Methode methodInA() in den Klassen B und C sind also zulässig. Die Klassen D und E haben keinen Zugriff auf die Variable valueInA und die Methode methodInA() der Klasse A.

Zugriffsmodifikator "protected":

Haben die Membervariablen und Methoden der Klasse A das Zugriffsrecht "protected", so besteht gegenüber dem Zugriffsrecht "<default>" ein etwas erweiterter Zugriff. Auf Membervariablen und Methoden mit dem Zugriffsrecht "protected" kann aus Klassen im gleichen Paket zugegriffen werden, und zusätzlich können auch Subklassen in anderen Paketen auf die von der Vaterklasse geerbten Membervariablen und Methoden zugreifen. Bedingung ist allerdings, dass nur auf die eigenen ererbten Membervariablen und Methoden zugegriffen wird. Wird jedoch in der Klasse E ein neues Objekt der Klasse A angelegt, so darf auf die protected geschützten Membervariablen und Methoden dieses Objekts nicht zugegriffen werden. Die Zugriffe z1 und z2 in der Klasse E sind also zulässig, die Zugriffe z3 und z4 sind jedoch nicht zulässig.

Zugriffsmodifikator "public":

Haben die Membervariablen und Methoden der Klasse A das Zugriffsrecht "public", so kann aus allen Klassen B, C, D und E auf die Membervariablen und Methoden der Klasse A zugegriffen werden.

3.6 Übungsaufgaben

Übungsaufgabe 3.1

Programmieren und testen Sie die in Bild 3.6 dargestellten Klassen. Mit den Klassen soll "main()" zu der gegebenen Textausgabe auf der Konsole führen. class Konto { ... ... } class PrivatGirokonto extends Konto { ... ... }

Konto kontonummer

display()

PrivatGirokonto

display()

bankleitzahl

kundenname kundenadresse zinssatz kontostand

Bild 3.6 Klassen "Konto" und "PrivatGirokonto"

Page 72: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

3 OOP II : Vererbung 72

public class Test { public static void main(String[] args) { PrivatGirokonto pGiro = new PrivatGirokonto( 32082455L, 20040020L,"Meyer, Boris", "Alphaeck 12, 22624 Hamburg", 3.20, 6123.25); pGiro.display(); } }

Auf der Konsole Meyer, Boris Alphaeck 12, 22624 Hamburg Kontonr. 32082455 BLZ 20040020 Zinsen 3.2% Kontostand 6123.25 DM

Page 73: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur

Ab diesem Abschnitt werden Klassen und Methoden aus dem Swing Toolset eingesetzt. Swing war der Name eines Projekts bei Sun Microsystems, in dem neue Komponenten und das zugehörige API (Application Programming Interface) entwickelt wurden. Im Gegensatz zum Vorläufer AWT (Abstract Windows Toolkit) benutzt Swing nur noch selten plattform-spezifische GUI Ressourcen (Graphical User Interface). Wenn z.B. ein Button gezeichnet werden soll, übernimmt Swing diese Aufgabe selbst und gibt den Auftrag nicht etwa an den GUI Manager weiter. − Als Vorteile fallen plattformspezifische Besonderheiten weg, und man ist nicht mehr auf

den kleinsten gemeinsamen Nenner der unterstützten Betriebssysteme angewiesen. − Dem stehen als Nachteile langsamere Ausführung und höherer Ressourcenbedarf gegen-

über. Außerdem werden Swing Applets von Browsern nur selten unterstützt.

Jedes Programm mit einem Swing GUI muss mindestens eine der folgenden Hauptkom-ponenten enthalten: JFrame, JWindow, JDialog oder JApplet. Die Hauptkomponenten stellen anderen Swing Komponenten Methoden zum Zeichnen und zur Ereignisbehandlung zur Verfügung. − JFrame: Ein Hauptfenster mit Rahmen, Kopfleiste und Standardschaltflächen. − JWindow: Ein rahmenloses Fenster. − JDialog: Ein sekundäres Fenster, das von einem anderen Fenster abhängig ist. − JApplet: Ein Fenster für einen Ausgabebereich in einem Browser.

Im folgenden ersten Swing Beispiel wird die Klasse "HelloWorld1" von JFrame abgeleitet. Die Programmumgebung ruft "paint" auf, wenn das Fenster neu gezeichnet werden soll. Das ist z.B. nach dem Programmstart der Fall oder wenn das Fenster verdeckt worden war und dann wieder sichtbar wird.

Beispiel, HelloWorld1

import java.awt.*; // For "Graphics" import javax.swing.*; // For "JFrame"

public class HelloWorld1 extends JFrame {

// Draw whenever necessary. Do some fancy graphics public void paint(Graphics g) { setBackground(Color.GREEN);

// The pink oval g.setColor(Color.PINK); g.fillOval(10, 10, 330, 100);

// The red outline. Java doesn't support wide lines, so a // 4-pixel wide line is simulated by drawing four ovals g.setColor(Color.RED); g.drawOval(10,10, 330, 100); g.drawOval( 9, 9, 332, 102); g.drawOval( 8, 8, 334, 104); g.drawOval( 7, 7, 336, 106);

// The text g.setColor(Color.BLACK); g.setFont(new Font("Arial", Font.BOLD, 46));

Page 74: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 74

g.drawString("Hello World!", 40, 75); }

public static void main(String[] args) { JFrame window = new HelloWorld1();

window.setTitle("Hello World 1"); window.setSize(360, 150); window.setLocation(100, 100); // Exit the application using the System exit method. // Use this only in applications window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 4.1 zeigt das Ausgabefenster. Der Koor-dinatenursprung liegt in der oberen linken Ecke des Gesamtfensters. Die Kopfleiste überdeckt deshalb hier noch einen Teil des Ovals. Der Fehler wird in den beiden folgenden Program-men korrigiert werden.

Das Swing-Hauptfenster JFrame und seine Komponenten

JFrame enthält eine Hauptkomponente Root Pane, die ihrerseits die in Bild 4.2 zu sehenden weiteren Komponenten besitzt.

Bild 4.2 Frame, Root Pane und Komponenten (aus [4])

Layered Pane (Geschichtete Scheibe) Die Layered Pane wird eingesetzt, um die zugehörigen Komponenten Content Pane und Menu Bar (Menüleiste) zu positionieren. Sie kann zusätzliche übereinander geschichtete Komponenten mit in z-Richtung frei wählbarer Reihenfolge enthalten.

Content Pane Dieser Container nimmt in der Regel die sichtbaren Komponenten eines Programms mit Ausnahme der Menüleiste auf.

Menu Bar (optional) Die Menüleiste enthält die Menüs einer Anwendung

Glass Pane (Glasscheibe) Die Glass Pane ist normalerweise durchsichtig und wird in der Regel nicht zur Ausgabe benutzt. Sie kann eingesetzt werden, wenn man das gesamte Fenster ansprechen will, um z.B. Mauseingaben abzufangen.

Im Programm "HelloWorld2" ist eine erste Vorgehensweise zur Grafikausgabe in der Content Pane zu finden.

Bild 4.1 Hello World 1

Page 75: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 75

Beispiel, HelloWorld2

import java.awt.*; import javax.swing.*;

public class HelloWorld2 extends JFrame {

public static void main(String[] args) { JFrame window = new HelloWorld2();

window.setTitle("Hello World 2"); window.setSize(360, 150); window.setLocation(100, 100); window.setDefaultCloseOperation(EXIT_ON_CLOSE);

JPanel mp = new MyPanel(); window.getContentPane().add(mp);

window.setVisible(true); } }

class MyPanel extends JPanel {

MyPanel() { setBackground(Color.GREEN); }

// Draw whenever necessary. Do some fancy graphics public void paintComponent(Graphics g) { super.paintComponent(g);

// The pink oval // ... Same code as in HelloWorld1 } }

Bild 4.3 zeigt das Ausgabefenster. Der Fehler des Programms "HelloWorld1" ist also behoben.

JPanel mp = new MyPanel(); window.getContentPane().add(mp);

Die Methode "getContentPane" gibt eine Refe-renz auf die Content Pane zurück. In die Content Pane wird dann eine Instanz von "MyPanel" eingefügt.

class MyPanel extends JPanel {

Die Klasse "MyPanel" wird von "JPanel" (Tafel, Platte) abgeleitet.

public void paintComponent(Graphics g) { super.paintComponent(g);

Die Programmumgebung ruft "paintComponent" auf, wenn das Fenster neu gezeichnet werden soll. Der Aufruf von "super.paintComponent" führt hier dazu, daas das Fenster mit der Hintergrundfarbe gefüllt wird.

Das Programm "HelloWorld3" zeigt eine zweite Vorgehensweise zur Grafikausgabe in der Content Pane. Man leitet das Programm von "JPanel" ab und instanziiert "JFrame" in "main".

Bild 4.3 Hello World 2

Page 76: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 76

Beispiel, HelloWorld3

import java.awt.*; import javax.swing.*; public class HelloWorld3 extends JPanel {

HelloWorld3() { setBackground(Color.GREEN); } // Draw whenever necessary. Do some fancy graphics public void paintComponent(Graphics g) { super.paintComponent(g);

// The pink oval // ... Same code as in HelloWorld1 }

public static void main(String[] args) { JFrame window = new JFrame("Hello World 3");

window.setSize(360, 150); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new HelloWorld3()); window.setVisible(true); } }

Das Ausgabefenster entspricht Bild 4.3, in der Kopfleiste wird aber "Hello World 3" aus-gegeben. In den weiteren Beispielen dieses Abschnitts wird in der Regel die in "Hello-World3" verwendete Programmstruktur eingesetzt.

Das Programm "RandomStrings" gibt 25 Zeichenketten aus. Farbe und Position der einzelnen Kopien werden dabei zufällig bestimmt. Die Schriftart wird ebenfalls zufällig aus fünf Vorgaben gewählt

Beispiel, RandomStrings

import java.awt.*; import javax.swing.*;

public class RandomSrrings extends JPanel { private Font font[] = new Font[5];

RandomSrrings () { // The font name can be a logical font name or a font face // name. A logical name must be either: Dialog, DialogInput, // Monospaced, Serif, SansSerif, or Symbol. If name is null, // the name of the new Font is set to Default font[0] = new Font("Serif", Font.BOLD, 14); font[1] = new Font("SansSerif", Font.BOLD + Font.ITALIC, 24); font[2] = new Font("Monospaced", Font.PLAIN, 20); font[3] = new Font("Dialog", Font.PLAIN, 30); font[4] = new Font("Serif", Font.ITALIC, 36); setBackground(Color.black); }

Page 77: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 77

public void paintComponent(Graphics g) { super.paintComponent(g);

int width = getSize().width; // Get width int height = getSize().height; // and height

for (int i = 0; i < 25; i++) { int fontNum = (int) (5 * Math.random()); g.setFont(font[fontNum]);

float hue = (float) Math.random(); // hue = Farbton // getHSBColor(float hue, float saturation, // float brightness) g.setColor(Color.getHSBColor(hue, 1.0F, 1.0F));

// Select the position of the string, at random int x = -50 + (int) (Math.random() * (width + 40)); int y = (int) (Math.random() * (height + 20));

// Draw the message g.drawString("Hello", x, y); } }

public static void main(String[] args) { JFrame window = new JFrame("Random Srrings");

window.setSize(360, 150); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new RandomSrrings()); window.setVisible(true); } }

Vom Programm wird das Fenster in Bild 4.4 ausgegeben. Das Programm hat aber noch Nachteile. − Wenn der Benutzer die Größe des

Fensters ändert, wird erneut "paintComponent" aufgerufen. Es werden dann neue Kopien von "Hello" ausgegeben und folglich ein verändertes Bild gezeichnet.

− Wenn ein ehemals verdeckter Teil des Fensters wieder sichtbar wird, wird nur dieser Bereich des Fensters erneuert. In Bild 4.5 ist zum Beispiel die rechte Bildhälfte neu gezeichnet worden.

Aufgabe 4.1

Schreiben Sie ein Programm "RandomStrings1". Ändern Sie dazu "RamdomStrings" so, dass das Bild beim Neuzeichnen unverändert bleibt.

Bild 4.4 Random Strings

Bild 4.5 Nur die rechte Bildhälfte wurde neu gezeichnet

Page 78: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 78

4.1 Maus- und Tastaturereignisse

Grafische Programme sind ereignisgesteuert. Sie warten und reagieren auf äußere Ereignisse (Events), wie z.B. das Verändern eines Fensters, das Bewegen der Maus oder das Betätigen einer Taste. Es gibt Ereignisquellen (Event sources) und Ereignisempfänger (Event listener).

In Tabelle 4.1 sind Listener Interfaces (Empfängerschnittstellen) für Maus und Tastatur und die zugehörigen Methoden zu finden. Der Java Begriff "Interface" wird in einem späteren Abschnitt genauer erläutert.

Tabelle 4.1 Listener Interface für Maus und Tastatur und zugehörige Methoden

Listener Interface Methoden Auslösende Aktion(en) MouseListener mouseClicked Eine Maustaste wurde gedrückt und wieder

losgelassen mouseEntered Der Mauszeiger "betritt" die Komponente mouseExited Der Mauszeiger verlässt die Komponente mousePressed Eine Maustaste wurde gedrückt mouseReleased Eine Maustaste wurde losgelassen MouseMotionListener mouseDragged Die Maus wurde bei gedrückter Taste bewegt mouseMoved Die Maus wurde bewegt, ohne dass eine Taste

gedrückt war KeyListener keyPressed Eine Taste wurde gedrückt keyReleased Eine Taste wurde losgelassen keyTyped Eine Taste wurde gedrückt und wieder losgelassen

Für Mausereignisse gibt es zwei Event Interfaces. "MouseListener" ist für Mausklicks zustän-dig, und "MouseMotionListener" reagiert auf Mausbewegungen. Diese Trennung ist aus Performancegründen vorgenommen worden. Wenn der Benutzer die Maustaste 1 gefolgt von der Maustaste 2 drückt und sie in derselben Reihenfolge wieder loslässt, werden zum Beispiel die folgenden Methoden in der gegebenen Reihenfolge aufgerufen:

1) mousePressed für Maustaste 1 2) mousePressed für Maustaste 2 3) mouseReleased für Maustaste 1 4) mouseClicked für Maustaste 1 5) mouseReleased für Maustaste 2 6) mouseClicked für Maustaste 2

4.1.1 Maus

Vom folgenden Programm wird das Fenster in Bild 4.6 ausgegeben. Der Kreis lässt sich bei gedrückter linker oder rechter Maustaste über das Fenster ziehen.

Beispiel, CircleAndMouse

import java.awt.*; import java.awt.event.*; // For MouseEvent, MouseMotionAdapter import javax.swing.*;

public class CircleAndMouse extends JPanel { private static final int R = 40; private static final Color BG_COLOR = Color.WHITE;

Bild 4.6 CircleAndMouse

Page 79: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 79

private static final Color FG_COLOR = Color.BLACK; private int x = 40, y = 40; // Center of circle

CircleAndMouse() { // Add MyMouseMotionListener to receive mouse motion events addMouseMotionListener(new MyMouseMotionListener()); setBackground(BG_COLOR); }

public void paintComponent(Graphics g) { super.paintComponent(g); draw(g); }

void draw(Graphics g) { display(g, FG_COLOR); } void erase(Graphics g) { display(g, BG_COLOR); }

void display(Graphics g, Color c) { g.setColor(c); g.drawOval(x-R, y-R, R+R, R+R); }

void moveTo(Graphics g, int xx, int yy) { erase(g); x = xx; y = yy; draw(g); }

public static void main(String[] args) { JFrame window = new JFrame("Circle and Mouse"); window.setSize(360, 200); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new CircleAndMouse()); window.setVisible(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { moveTo(getGraphics(), me.getX(), me.getY()); } } }

addMouseMotionListener(new MyMouseMotionListener());

Mit dieser Anweisung wird die Klasse "MyMouseMotionListener" als Ereignisempfänger angemeldet. Danach wird ihre Methode "mouseDragged" (und gegebenenfalls auch "mouse-Moved") bei den zugehörigen Mausereignissen aufgerufen.

class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { moveTo(getGraphics(), me.getX(), me.getY()); } }

Die Klasse "MyMouseMotionListener" ist vollständig in die Klasse "CirleAndMouse" ein-gebettet. "MyMouseMotionListener" ist damit eine innere Klasse (inner class). Eine innere Klasse hat Zugriff auf alle Daten und Methoden der umgebenden Klasse. Das gilt auch dann, wenn diese Daten und Methoden als "private" vereinbart worden sind. Adapterklassen, wie hier z.B. "MouseMotionAdapter" werden in einem späteren Abschnitt erläutert.

Page 80: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 80

Das folgende Programm MouseDemo1 enthält sowohl einen "MouseListener" als auch einen "MouseMotionListener". Darüber hinaus zeigt es, wie man Doppelklicks feststellen kann, die jeweilige Maustaste bestimmt und beim Mausklick zusätzlich gedrückte Tasten ermittelt.

Beispiel, MouseDemo1

import java.awt.event.*; import javax.swing.*; public class MouseDemo1 extends JPanel { private long previousTime = 0; MouseDemo1() { addMouseMotionListener(new MyMouseMotionListener()); addMouseListener(new MyMouseListener()); } void printMessageMousePressed(String s, MouseEvent me) { long time = me.getWhen(); // Timestamp in ms if(time - previousTime < 300) s += "Double "; previousTime = time; if(me.isShiftDown()) // Test Shift s += "Shift "; if(me.isControlDown()) // Test Control s += "Control "; int mods = me.getModifiers(); if((mods & InputEvent.BUTTON1_MASK) != 0) System.out.println(s + "Button 1"); // Left mouse button if((mods & InputEvent.BUTTON2_MASK) != 0) System.out.println(s + "Button 2"); // Middle or wheel if((mods & InputEvent.BUTTON3_MASK) != 0) System.out.println(s + "Button 3"); // Right } void printMessageMouseDragged(String s, MouseEvent me) { if(me.isShiftDown()) // Test Shift s += "Shift "; if(me.isControlDown()) // Test Control s += "Control "; int mods = me.getModifiers(); if((mods & InputEvent.BUTTON1_MASK) != 0) System.out.println(s + "Button 1"); // Left mouse button if((mods & InputEvent.BUTTON2_MASK) != 0) System.out.println(s + "Button 2"); // Middle or wheel if((mods & InputEvent.BUTTON3_MASK) != 0) System.out.println(s + "Button 3"); // Right }

Page 81: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 81

public static void main(String[] args) { JFrame window = new JFrame("Mouse Demo 1"); window.setSize(360, 200); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new MouseDemo1()); window.setVisible(true); } // --------------------------------------------------------- class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { printMessageMouseDragged("mouseDragged ", me); } } class MyMouseListener extends MouseAdapter { public void mousePressed(MouseEvent me) { printMessageMousePressed("mousePressed ", me); } } }

Auf der Konsole mousePressed Button 1

mousePressed Button 1 // Beginn eines Doppelklicks mousePressed Double Button 1

mousePressed Shift Button 3 // Rechte Maustatse mousePressed Shift Control Button 3

mousePressed Shift Button 1 // Shift + Maustaste gedrückt und Maus bewegt mouseDragged Shift Button 1 mouseDragged Shift Button 1 ...

Aufgabe 4.2

Schreiben Sie das Programm "Duke", mit dem ein in der Datei "Duke.gif" gespeichertes Bild geladen und dargestellt werden kann (Bild 4.7). "Duke" soll an die Position eines Mausklicks springen und sich bei gedrückter Maustaste bewegen lassen. Der folgende Programmaus-schnitt zeigt, wie man eine Bilddatei lesen und ein Bild zeichnen kann.

... public class Duke extends JPanel { private Image duke; private int hDuke, wDuke; // Height and width of Duke ...

Duke() { addMouseListener(new MyMouseListener());

Bild 4.7 Duke

Page 82: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 82

addMouseMotionListener(new MyMouseMotionListener()); setBackground(BG_COLOR);

duke = getToolkit().getImage("Duke.gif");

MediaTracker mt = new MediaTracker(this); mt.addImage(duke, 0); // Identifier id = 0 // Wait until image with identifier 0 has been loaded try { mt.waitForID(0); } catch (InterruptedException e) {}

wDuke = duke.getWidth(this); hDuke = duke.getHeight(this); }

... // x, y is the upper left corner of the picture void draw(Graphics g) { g.drawImage(duke,x-wDuke,y-hDuke,this); } ...

Die Methode "getToolkit" gibt eine Referenz auf einen "Werkzeugkasten" für die aktuelle Umgebung zurück. Zu diesem Werkzeugkasten gehört die Methode "getImage", die den Lese-vorgang für die als Parameter übergebene Bilddatei anstößt. (Wenn nicht der vollständige Pfad, sondern nur ein Dateiname angegeben wird, erwartet Eclipse die Datei im Projekt-verzeichnis, also im Verzeichnis, in dem auch die Datei ".project" gespeichert ist.)

Die Klasse "MediaTracker" ermöglicht es, auf den Abschluss des Lesevorgangs zu warten. Mit "addImage" wird "duke" in die Liste der zu verfolgenden Lesevorgänge aufgenommen, und es wird der Identifier 0 zugewiesen. Die Methode "waitForID" kehrt erst dann in das aufrufende Programm zurück, wenn die Datei mit dem angegebenen Identifier vollständig gelesen worden ist.

4.1.2 Tastatur

Im folgenden Programm "CircleAndKeys" lässt sich ein Kreis mit den Pfeiltasten der Tastatur bewegen. Dazu enthält "CircleAndKeys" einen "KeyListener". Das vom Programm ausge-gebene Fenster stimmt Bild 4.6 überein.

Beispiel, CircleAndKeys

import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class CircleAndKeys extends JPanel { private static final int R = 40; private static final Color BG_COLOR = Color.WHITE; private static final Color FG_COLOR = Color.BLACK; private int x = 40, y = 40; // Center of circle

CircleAndKeys() { setBackground(BG_COLOR); addKeyListener(new MyKeyListener()); // Request that this component gets the input focus

Page 83: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 83

setFocusable(true); requestFocus(); }

public void paintComponent(Graphics g) { super.paintComponent(g); draw(g); }

void draw(Graphics g) { display(g, FG_COLOR); } void erase(Graphics g) { display(g, BG_COLOR); }

void display(Graphics g, Color c) { g.setColor(c); g.drawOval(x-R, y-R, R+R, R+R); }

void moveTo(Graphics g, int xx, int yy) { erase(g); x = xx; y = yy; draw(g); }

public static void main(String[] args) { JFrame window = new JFrame("Circle and Keys");

window.setSize(360, 200); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new CircleAndKeys()); window.setVisible(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyKeyListener extends KeyAdapter { public void keyPressed(KeyEvent ke) { switch(ke.getKeyCode()) { case KeyEvent.VK_DOWN: // Valid key arrow down moveTo(getGraphics(), x, y+5); break; case KeyEvent.VK_UP: // Arrow up moveTo(getGraphics(), x, y-5); break; case KeyEvent.VK_LEFT: // Arrow left moveTo(getGraphics(), x-5, y); break; case KeyEvent.VK_RIGHT: // Arrow right moveTo(getGraphics(), x+5, y); break; } } } }

Das folgende Programm "KeyDemo" zeigt, wie man auf wieder losgelassene Tasten reagieren kann. Im Gegensatz zu gedrückten Tasten gibt es in diesem Fall keine Selbstwiederholung (auto repeat). Zusätzlich werden die Funktionstasten "Shift" und "Ctrl" abgefragt.

Beispiel, KeyDemo

import java.awt.event.*; import javax.swing.*;

public class KeyDemo extends JPanel {

KeyDemo() { addKeyListener(new MyKeyListener()); setFocusable(true); requestFocus(); }

Page 84: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 84

public static void main(String[] args) { JFrame window = new JFrame("Key Demo");

window.setSize(360, 200); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new KeyDemo()); window.setVisible(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyKeyListener extends KeyAdapter {

public void keyReleased(KeyEvent ke) { String s = "KeyReleased ";

if(ke.isShiftDown()) s += "Umschalt "; if(ke.isControlDown()) s += "Strg ";

switch(ke.getKeyCode()) { // Two examples for valid key constants case KeyEvent.VK_F1: s += "Key F1"; break; case KeyEvent.VK_F2: s += "Key F2"; break; default: // Methods in class KeyEvent s += KeyEvent.getKeyText(ke.getKeyCode()); } System.out.println(s); } } }

Auf der Konsole KeyReleased Rechts // Pfeiltaste -> KeyReleased Links // Pfeiltaste <- KeyReleased Key F1 // Funktionstaste F1 KeyReleased Umschalt Key F1 // Shift + F1 KeyReleased Umschalt // Shift KeyReleased Strg Key F2 // Strg + F2 KeyReleased Strg // Strg ...

Page 85: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

4 Grafikprogramme, Maus und Tastatur 85

Aufgabe 4.3 Schreiben Sie ein Programm "Ellipse" zur grafischen Aus-gabe der Funktion, wie es Bild 4.8 zeigt. Die folgende Gleichung beschreibt eine Ellipse mit den beiden Halb-achsen a und b.

x

a

y

b

2

2

2

21+ =

− Mit der Taste F1 lässt sich die Farbe von Achsen-kreuz, Beschriftung und Ellipse ändern.

− Wenn der Benutzer die Fenstergröße ändert, soll sich das Diagramm der neuen Größe anpassen.

4.2 Übungsaufgaben

Übungsaufgabe 4.1 Schreiben Sie ein Programm "RandomStrings2". Ändern Sie dazu das in Aufgabe 4.1 geschriebene Programm "RandomString1" so, dass die Anzahl der Strings pro-portional zur Fenstergröße anwächst, die "Stringdichte" also näherungsweise gleich bleibt. Übungsaufgabe 4.2 Schreiben Sie ein Programm "StringsAndMouse". Ändern Sie dazu das in Aufgabe 4.1 geschriebene Programm "RandomString1" so, dass neue Strings erzeugt und ausgegeben werden, wenn der Benutzer eine Maustaste drückt. Übungsaufgabe 4.3 Schreiben Sie ein Programm "MouseAndKeys". Ändern Sie dazu das Programm "CircleAndMouse" aus dem vorigen Abschnitt so, dass − mit den Funktionstasten F1 bis F4 unterschiedliche Farben für den Kreis ausgewählt

werden können und − sich der Kreis sowohl mit der Maus als auch mit den Pfeiltasten der Tastatur bewegen

lässt.

Bild 4.8 Ellipse

Page 86: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets

Ein erstes Applet ist schon im Abschnitt 1.1 zu finden. Dort ist das Applet von der AWT Klasse "Applet" abgeleitet worden. In den folgenden Beispielen wird stattdessen die Swing Klasse "JApplet" eingesetzt. Vorteile und Nachteile sind schon im vorausgehenden Abschnitt erläutert worden.

Beispiel, HelloWorldApplet

import java.awt.*; import javax.swing.*;

public class HelloWorldApplet extends JApplet { public void init () { getContentPane().add(new MyPanel()); } }

class MyPanel extends JPanel { private Font font;

MyPanel() { font = new Font("Arial", Font.BOLD, 46); setBackground (Color.GREEN); }

public void paintComponent(Graphics g) { super.paintComponent(g);

g.setColor(Color.PINK); g.fillOval(10, 10, 330, 100);

g.setColor(Color.RED); g.drawOval(10,10, 330, 100); g.drawOval( 9, 9, 332, 102); g.drawOval( 8, 8, 334, 104); g.drawOval( 7, 7, 336, 106);

g.setColor(Color.BLACK); g.setFont(font); g.drawString("Hello World!", 40, 75); } }

Datei "HelloWorldApplet.html"

<HTML> <APPLET CODE="HelloWorldApplet.class" WIDTH=352 HEIGHT=120> </APPLET> </HTML>

Vom Appletviewer wird das Fenster in Bild 5.1 ausgegeben.

Bild 5.1 HelloWorldApplet

Page 87: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 87

Bevor ein Applet aktiv wird, instanziiert der Browser (oder der Appletviewer) zunächst ein Objekt der von "JApplet" abgeleiteten Klasse, im vorausgehenden Beispiel also von "HelloWorldApplet". Einige Methoden, die vom Browser aufgerufen werden

− public void init() Nach der Instanziierung ruft der Browser "init" auf, um dem Applet die Möglichkeit zu geben, Initialisierungen vorzunehmen. Die Methode "init" wird während der Lebensdauer eines Applets nur einmal aufgerufen.

− public void start() Der Browser ruft "start" immer dann auf, wenn das Applet sichtbar wird. Im Gegensatz zur Initialisierung kann das Starten eines Applets also mehrfach erfolgen. Die Methode kann z.B. eine Animation starten.

− public void paintComponent(Graphics) Durch Aufruf von "paintComponent" fordert der Browser das Applet auf, sich auf dem Bildschirm darzustellen. Die Methode wird z.B. aufgerufen, wenn das Browserfenster verdeckt war und dann wieder neu gezeichnet werden muss.

− public void stop() Der Browser ruft "stop" auf, wenn ein Applet vorübergehend unsichtbar wird, weil der Benutzer es beispielsweise vom Bildschirm gescrollt hat. Die Methode kann z.B. eine Animation anhalten.

− public void destroy() Durch Aufruf von "destroy" teilt der Browser dem Applet mit, dass es nicht mehr benötigt wird. Das ist z.B. der Fall, wenn der Benutzer den Browser beendet. Die Methode kann z.B. einen Thread (Programmfaden) "zerstören", der vom Applet angelegt worden ist.

Darüber hinaus gibt es weitere Methoden. Einige werden verwendet, um auf äußere Ereignisse (events) zu reagieren, wie z.B. auf Tastatur- oder Mausereignisse. Unterschiede zwischen Applikationen (Programmen) und Applets

− Eine Applikation wird vom Java-Interpreter durch Aufruf von "main" gestartet. Zum Starten eines Applets instanziieren Web-Browser oder Appletviewer die von Applet abgeleitete Klasse und rufen danach die Methoden "init" usw. auf.

− Im Gegensatz zu Applikationen darf ein Applet in der Regel aus Sicherheitsgründen nicht auf Dateien des Rechners zugreifen.

− Ein Applet arbeitet immer im Grafikmodus, eine Applikation kann sich dagegen auf Konsolenausgabe beschränken.

Das folgende Applet "OneLine" zeigt, dass sich die schon bekannte Vorgehensweise zur Ereignisbehandlung unverändert auf Applets übertragen lässt. Zum Zeichnen einer Linie drückt man eine Mautaste und zieht den Mauscursor bei gedrückt gehaltener Maustaste. Die Linie folgt dem Cursor, bis die Maustaste wieder losgelassen wird. Mit einer beliebigen Taste der Tastatur kann man die Linienfarbe verändern.

Beispiel, OneLine

import java.awt.*; import java.awt.event.*;

Page 88: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 88

import javax.swing.*;

public class OneLine extends JApplet { public void init() { getContentPane().add(new OneLinePanel()); } }

class OneLinePanel extends JPanel { private final static Color COLOR[] = { Color.BLACK, Color.WHITE }; private Point from = new Point(-1, -1), to = new Point(-1, -1); private int colInd = 0;

OneLinePanel() { addMouseListener(new MyMouseListener()); addMouseMotionListener(new MyMouseMotionListener()); addKeyListener(new MyKeyListener()); setFocusable(true); requestFocus(); setBackground (Color.LIGHT_GRAY); }

public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(COLOR[colInd]); g.drawLine(from.x, from.y, to.x, to.y); g.setColor(Color.BLACK); g.drawString("Line from (" + from.x + "," + from.y + ") to (" + to.x + "," + to.y + ")", 0, 10); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyMouseListener extends MouseAdapter { public void mousePressed(MouseEvent me){ from = to = me.getPoint(); repaint(); } } class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { to = me.getPoint(); repaint(); } } class MyKeyListener extends KeyAdapter { public void keyPressed(KeyEvent ke) { colInd = ++colInd % COLOR.length; repaint(); } } }

Bild 5.2 zeigt ein Beispiel zum Fenster, das vom Appletviewer ausgegeben wird. Aufgabe 5.1 Schreiben Sie das Applet "OneLIne" so um, dass man es wahlweise als Applet oder als Programm (Application) starten kann. Verwenden Sie dabei eine Vor-gehensweise, die sich ohne größere Ände-rungen auf andere Applets übertragen lässt.

Bild 5.2 Applet OneLine

Page 89: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 89

5.1 Das Einbinden eines Applets Ein Applet wird mit einem Applet-Tag (Kennung, Markierung) in ein HTML Dokument eingebunden3. Die "Minimalform" eines Applet-Tags ist schon bekannt: <APPLET CODE="HelloWorld.class" WIDTH=350 HEIGHT=120> </APPLET>

Die Datei "HelloWorld.class" wird in diesem Fall im selben Verzeichnis wie das HTML-Dokument erwartet. In Tabelle 5.1 sind einige weitere Angaben zu finden, die in einem Applet-Tag zulässig sind. Tabelle 5.1 Einige im Applet-Tag zulässige Angaben

Angabe Bedeutung CODEBASE Verzeichnis, in dem die ".class"-Dateien gesucht werden (beliebige URL) ALIGN Ausrichtung des Fensters (z.B. left oder right) HSPACE Rand rechts und links vom Applet VSPACE Rand über und unter dem Applet

In der folgenden HTML Datei "AppletAndText" wird das Applet "OneLIne" in Text einge-bettet. Die Angaben im Applet Tag führen dazu, dass der Browser − das Applet im Unterverzeichnis "classes" zum Verzeichnis der HTML Datei sucht, − das Applet-Fenster rechtsbündig ausrichtet und − die vorgegebenen Ränder einhält. Datei "AppletAndText.html" <HTML> <p>An array is an important data structure in any programming language. An array is a fixed-length structure that stores <APPLET CODEBASE="classes" CODE="OneLine.class" WIDTH=200 HEIGHT=160 ALIGN=right HSPACE=25 VSPACE=15> </APPLET> multiple values of the same type. You can group values of the same type within arrays. Arrays are supported directly by the Java programming language; there is no array class. Arrays are implicit extensions of the Object class, so you can assign an array to a variable whose type is declared as Object. The Java platform groups its classes into functional packages. Instead of writing your own classes, you can use one provided by the platform. Most of the classes discussed in this chapter are members of the java.lang package. All the classes in the java.lang package are available to your programs automatically.</p> </HTML>

3 Die Einbindung eines Applets mit Embed- und Object-Tags wird hier nicht erläutert.

Page 90: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 90

Vom Browser wird Bild 5.3 ausgegeben. Bei gedrückter Maustaste lässt sich eine Linie im Appletfenster zeichnen.

Center Tag

Mit dem HTML Zentrierungs-Tag <CENTER> ... </CENTER> lässt sich ein Applet-Fenster zentriert ausgeben.

... An array is a fixed-length structure that stores <CENTER><APPLET CODEBASE="classes" CODE="CircleAndMouse.class" WIDTH=200 HEIGHT=160> </APPLET></CENTER> multiple values of the same type. You can group values of the same ...

Param Tag Man kann in einem Applet Parameter aus der zugehörigen HTML-Datei lesen. Dazu werden Param-Tags verwendet, die in das Applet-Tag eingebettet sind. In der Datei "TestParamTag.html" sind als Beispiel zwei Parameter mit den Namen (name) "initialX" bzw. "initialY" und ihren Werten (value) "10" bzw. "12" zu finden. Datei "TestParamTag.html" <APPLET CODE="TestParamTag.class" WIDTH=350 HEIGHT=120> <PARAM name="initialX" value=10> <PARAM name="initialY" value=12> </APPLET>

ImApplet können die Paramter mit der Methode

public String getParameter(String name)

Bild 5.3 Das Appletfenster wird in den Text eingebettet

Page 91: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 91

als String gelesen werden. Das folgenden Programm "TestParamTag.java" zeigt die Vor-gehensweise. Datei "TestParamTag.java" import java.awt.*; import javax.swing.*; public class TestAppletTag extends JApplet { private int startX, startY; public void init() { try { startX = Integer.parseInt(getParameter("initialX")); startY = Integer.parseInt(getParameter("initialY")); } catch (NumberFormatException e) { startX = 0; startY = 0; } } public void paint(Graphics g) { System.out.println("startX = " + startX); System.out.println("startY = " + startY); } }

Auf der Konsole startX = 10 startY = 12 Aufgabe 5.2

Schreiben Sie ein Applet "Funktion" zur grafischen Ausgabe der folgenden Funktion: y a a x a x a x a x= + ⋅ + ⋅ ⋅ + ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅0 1 2 3 43 5sin( ) sin( ) sin( )π π π Bild 5.4 zeigt, wie die Funktion ausgegeben werden sollen.

− Lesen Sie die benötigen Koeffizienten a0 bis a4 aus der HTML-Datei ein.

− Wenn das Applet mit einem Applet-viewer ausgeführt wird und der Benutzer die Fenstergröße ändert, soll sich die Größe des Diagramms der neuen Fenstergröße anpassen.

Bild 5.4 a0 = a1 = 0, a2 = 5, a3 = 1.667, a4 = 1

Page 92: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 92

5.2 Übungsaufgaben Übungsaufgabe 5.1

a) Schreiben Sie ein Applet "Rechteck" zum Zeichnen eines Rechtecks. � Man drückt eine Mautaste und legt damit den ersten Eckpunkt fest. � Bei gedrückt gehaltener Maustaste zieht man den Mauscursor auf den zweiten Eck-

punkt. � Während der Mauscursor bewegt wird, gibt das Applet jeweils das derzeit aktuelle

Rechteck aus. Erster und zweiter Eckpunkt sollen beliebig zueinander positioniert werden können.

b) Sinngemäß wie a), es soll aber ein Kreis ausgegeben werden. Übungsaufgabe 5.2

Das gegebene Programm "Klau-sur" gibt auf der Konsole eine einfache Übersicht über das Ergebnis einer Klausur aus (Bild 5.5).

Wandeln Sie das Programm in ein Applet um, das eine ähnliche Übersicht im Appletfenster aus-gibt. public class Klausur { private final String RANGE[] = {" 0..4 ", " 5..6 ", " 7..9 ", "10..12","13..15"}; private final String STAR = " * ", BLANKS = " "; private int numStud[] = new int[RANGE.length], sum = 0, max = 0; Klausur() { numStud[0] = 3; numStud[1] = 3; numStud[2] = 6; numStud[3] = 5; numStud[4] = 2; } public void diagram() { for(int i = 0; i < RANGE.length; i++) System.out.print(" " + RANGE[i]); System.out.println(); for(int i = 0; i < 2 + 8*RANGE.length; i++) System.out.print('-'); System.out.println();

0..4 5..6 7..9 10..12 13..15 ------------------------------------------ * * * * * * * * * * * * * * * * * * *

Participants: 19 Bild 5.5 Übersicht über ein Klasusurergebnis

Page 93: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

5 Applets 93

for(int i = 0; i < numStud.length; i++) { sum += numStud[i]; max = Math.max(max, numStud[i]); } for(int i = 0; i < max; i++) { String s = ""; for(int j = 0; j < RANGE.length; j++) s += (i < numStud[j])? STAR: BLANKS; System.out.println(s); } System.out.println("\nParticipants: " + sum); } public static void main(String[] args) { Klausur klausur = new Klausur(); klausur.diagram(); } }

Page 94: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP III : Polymorphie, Abstrakte Klassen und Interfaces

6.1 Polymorphie und spätes Binden Frühes Binden (Statisches Binden, Early Binding) bedeutet, dass Compiler, Linker und Loader schon vor der Ausführung eines Programms die tatsächliche physikalische Adresse einer Methode (eines Unterprogramms) in den Maschinencode einfügen. Frühes Binden wird z.B. in Assembler- und in C-Programmen verwendet. In dem nachfolgenden Beispiel "EmployeeApp" werden einer Referenz auf die Basisklasse "Employee" nacheinander Instanzen der abgeleiteten Klassen "Worker", "SalesAgent" und "Manager" zugewiesen. Die Konsolenausgabe zeigt, dass immer die displaySalary()-Methode der Klasse aufgerufen wird, auf die die Basisklassenreferenz aktuell zeigt. Dies ist eine Ausprägung der Polymorphie, welche ein wichtiges Konzept des objektorientierten Programmierens ist. Die Polymorphie von Objekten erlaubt es, wieder verwendbaren Code zu schreiben, der nur Referenzen auf Objekte der Basisklasse enthält, wie im nachfolgenden Beispiel der array Employee[] empl. Trotzdem können Objekte der gesamten Vererbungshierarchie in ihm abgelegt werden, und es wird stets die "passende" Methode displaySalary() der entsprechenden abgeleiteten Klasse aufgerufen.

Beispiel, EmployeeApp class Employee { private String name; Employee(String n) { name = new String(n); } void displayName() { System.out.print(name + " " ); } void displaySalary() {} // For "empl[i].displaySalary();" } //---------------------------------------------------------------- class Worker extends Employee { protected double hourlyWage, hours; Worker(String n, double hW, double h) { super(n); hourlyWage = hW; hours = h; } void displaySalary() { System.out.println(hourlyWage * hours + " EUR"); } } //---------------------------------------------------------------- class SalesAgent extends Worker { protected double commission, count; SalesAgent(String n, double hW, double h, double c, double cn) { super(n, hW, h); commission = c; count = cn;

Page 95: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 95

} void displaySalary() { System.out.println(hourlyWage * hours + commission*count + " EUR"); } } //---------------------------------------------------------------- class Manager extends Employee { private double salary; Manager(String n, double s) {super(n); salary = s; } void displaySalary() { System.out.println(salary + " EUR"); } } //---------------------------------------------------------------- public class EmployeeApp { public static void main(String[] args) throws IOException { int sel; Employee[] empl = new Employee[3]; BufferedReader din = new BufferedReader( new InputStreamReader(System.in)); for (int i= 0; i < empl.length; i++) { do { System.out.println("Was soll erzeugt werden?"); System.out.println("- Worker (1)\n" + "- SalesAgent (2)\n" + "- Manager (3)"); System.out.print("Eingabe: "); sel = Integer.parseInt(din.readLine()); switch(sel) { case 1: empl[i] = new Worker("Meyer, Klaus", 15.82, 151.00); break; case 2: empl[i] = new SalesAgent("Hamer, Peter", 8.80, 150.0, 60.28, 22.0); break; case 3: empl[i] = new Manager("Kramer, Hans", 3501.27); break; default: System.out.println("Ungültige Eingabe"); } } while (sel < 1 || sel > 3); } for (int i= 0; i < empl.length; i++) { empl[i].displayName();

Page 96: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 96

empl[i].displaySalary(); } } }

Auf der Konsole: Was soll erzeugt werden? - Worker (1) - SalesAgent (2) - Manager (3) Eingabe: 1 Was soll erzeugt werden? - Worker (1) - SalesAgent (2) - Manager (3) Eingabe: 2 Was soll erzeugt werden? - Worker (1) - SalesAgent (2) - Manager (3) Eingabe: 3 Meyer, Klaus 2388.82 EUR Hamer, Peter 2646.16 EUR Kramer, Hans 3501.27 EUR

Wenn in einer abgeleitete Klasse eine Methode definiert wird, die den gleichen Namen, den gleichen Rückgabetyp und die gleichen Parameter wie eine Methode der Oberklasse besitzt, dann überschreibt diese Methode die gleichnamige Methode der Oberklasse (Overriding). Im vorausgehenden Programm ist das für displaySalary() der Fall. Für überschriebene Methoden gilt, dass das zur Programmlaufzeit zugewiesene Objekt die Methode bestimmen. Die Entscheidung, welche Version von displaySalary() jeweils angesprochen wird, findet also erst zur Ausführungszeit des Programms statt und wird als Spätes Binden (Dynamisches Binden, Late binding) bezeichnet. Beachten Sie, dass die Methode displaySalary() in der Basisklasse Employee noch einen leeren Methodenrumpf hat, da man für einen allgemeinen Angestellten noch kein konkretes Gehalt berechnen kann. Das Auswählen der "richtigen" Methode zur Laufzeit des Programms ist in Java zwar effizient implementiert, der Aufwand ist aber dennoch höher als beim Frühen Binden. Wenn das Späte Binden aus Laufzeitgründen verhindert werden soll, lässt sich das folgendermaßen erreichen: − Private Methoden ("private") sind in einer abgeleiteten Klasse nicht sichtbar und können

folglich nicht überschrieben werden. − Mit dem zusätzlichen Schlüsselwort "final" lässt sich festlegen, dass eine Methode in

abgeleiteten Klassen nicht überschrieben werden kann. − Klassenmethoden ("static") können nicht überschrieben werden.

Das nachfolgende Applet ist ebenfalls ein Beispiel zur Polymorphie. Wenn das Applet "ShapeAndMouse" ausgeführt wird, kann man bei gedrückter linker Maustaste wahlweise einen Kreis oder ein Rechteck über das Appletfenster ziehen. Mit der rechten Maustaste lässt sich dabei zwischen Kreis zum Rechteck umschalten. Hier wird die Methode display() der Basisklsse Shape in den abgeleiteten Klassen Circle und Rect überschrieben. Die Aufgabe der Methode display() ist es, das jeweilige Objekt auf der Zeichenebene zu zeichen.

Page 97: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 97

Beispiel, ShapeAndMouse import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ShapeAndMouse extends JApplet { public void init() { getContentPane().add(new SMPanel()); } } class SMPanel extends JPanel { private Circle circle = new Circle(100, 100, 40); private Rect rect = new Rect(100, 100, 70, 70); private Shape shape = circle; SMPanel() { addMouseMotionListener(new MyMouseMotionListener()); addMouseListener(new MyMouseListener()); setBackground(Shape.BG_COLOR); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); } public void paintComponent(Graphics g) { super.paintComponent(g); shape.draw(g); } class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { if(!me.isMetaDown()) // Left button pressed? shape.moveTo(getGraphics(), me.getX(), me.getY()); } } class MyMouseListener extends MouseAdapter { public void mousePressed(MouseEvent me) { if(me.isMetaDown()) { // Right button pressed? shape.erase(getGraphics()); if(shape == circle) shape = rect; else shape = circle; shape.moveTo(getGraphics(), me.getX(), me.getY()); } } } } //--------------------------------------------------------------- class Shape { static final Color BG_COLOR = Color.LIGHT_GRAY; static final Color FG_COLOR = Color.BLACK; private int x, y; // Reference point Shape(int x, int y) {this.x = x; this.y = y;}

Page 98: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 98

int getX() { return x; } int getY() { return y; } void display(Graphics g, Color c) {} void draw(Graphics g) {display(g, FG_COLOR);} void erase(Graphics g) {display(g, BG_COLOR);} void moveTo(Graphics g, int x, int y) { erase(g); this.x = x; this.y = y; draw(g); } } //--------------------------------------------------------------- class Circle extends Shape { int r; Circle(int x, int y, int r) { super(x, y); this.r = r; } void display(Graphics g, Color c) { g.setColor(c); g.drawOval(getX(), getY(), r+r, r+r); } } //--------------------------------------------------------------- class Rect extends Shape { int width, height; Rect(int x, int y, int w, int h) { super(x, y); width = w; height = h; } void display(Graphics g, Color c) { g.setColor(c); g.drawRect(getX(), getY(), width, height); } }

Vom Appletviewer wird Bild 6.1 ausgegeben.

Aufgabe 6.1

a) Erweitern Sie das Programm so, dass sich zu-sätzlich zu Kreis und Rechteck auch ein Kreis-bogen über das Appletfenster ziehen lässt. Mit der rechten Maustaste soll zyklisch zwischen Kreis, Rechteck und Kreisbogen umgeschaltet werden können.

b) Was geschieht, wenn man das Programm um eine weitere Klasse, wie z.B. "Arc", erweitert und dabei die zugehörige Funktion "display" vergisst?

Bild 6.1 Applet ShapeAndMouse

Page 99: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 99

6.2 Abstrakte Klassen und Interfaces Abstrakte Klassen und abstrakte Methoden

Eine Klasse wird durch das Schlüsselwort "abstract" zur abstrakten Klasse. Abstrakte Klassen können nur als Oberklassen für andere Klassen verwendet werden. Es ist nicht möglich, ein Objekt einer abstrakten Klasse zu vereinbaren, d.h. die Klasse zu instanziieren. abstract class Shape { // Abstakte Klasse ...

Abstrakte Klassen enthalten häufig abstrakte Methoden. Eine abstrakte Methode beginnt ebenfalls mit "abstract". Zusätzlich wird der "Methodenkörper" einschließlich des geschweif-ten Klammernpaars durch ein Semikolon ersetzt. Wenn nur eine einzige Methode einer Klasse abstrakt ist, so ist die Klasse selber zwangsläufig abstrakt, und ist damit mit dem Schlüsselwort "abstract" zu deklarieren. abstract class Shape { // Abstarkte Klasse ... abstract void display(Graphics g, Color c); // Abstrakte Methode ...

Eine von einer abstrakten Klasse abgeleitete Klasse erbt natürlich auch die abstrakten Methoden. − Nur wenn die abgeleitete Klasse für alle geerbten abstrakten Methoden konkrete Imple-

mentierungen enthält, ist sie nicht mehr abstrakt, und es lassen sich Objekte vereinbaren. − Wenn die abgeleitete Klasse auch nur für eine der abstrakten Methoden keine konkrete

Implementierungen bereitstellt, ist sie ebenfalls wieder abstrakt. Sie muss dann mit dem Schlüsselwort "abstract" beginnen.

Beispiel, "Shape" als abstrakte Klasse

abstract class Shape { // Abstarkte Klasse static final Color BG_COLOR = Color.LIGHT_GRAY; static final Color FG_COLOR = Color.BLACK; private int x, y; Shape(int x, int y) {this.x = x; this.y = y;} int getX() { return x; } int getY() { return y; } abstract void display(Graphics g, Color c); // Abstrakte Methode void draw(Graphics g) {display(g, FG_COLOR);} void erase(Graphics g) {display(g, BG_COLOR);} void moveTo(Graphics g, int x, int y) { erase(g); this.x = x; this.y = y; draw(g); } }

Page 100: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 100

Das Beispiel zeigt eine sinnvolle Anwendung. Die Klasse "Shape" aus dem Programm "ShapeAndMouse" ist nun abstrakt. Als Folge kann man von Klassen, die von ihr abgeleitet werden, nur dann Objekte vereinbaren, wenn sie eine konkrete Implementierung der Methode "display()" enthalten. Daher kann nach dieser Änderung der Fehler aus Unterpunkt c) der Aufgabe 6.1 nicht mehr auftreten!

Interfaces Ein Interface (Schnittstelle) ist eine spezielle Klasse die ausschließlich abstrakte Methoden und Konstanten enthält. Statt "class" wird das Schlüsselwort "interface" verwendet. Beispiel, Interface "Drawable" Datei "Drawable.java" import java.awt.*;

public interface Drawable { public static final Color BG_COLOR = Color.lightGray; public static final Color FG_COLOR = Color.black; public abstract void display(Graphics g, Color c); }

Alle abstrakten Methoden eines Interface sind durch Voreinstellung "public" und "abstract". Man sollte das Schlüsselwort "public" aber hinzufügen, man muss es aber nicht. Andere Modifizierer, wie z.B. "private", sind nicht zulässig. Bei der Definition von Konstanten besteht bezüglich der Angabe der Modifikatoren "public", "static" und "final" völlige Freiheit. Sie können angegeben werden, sie können aber auch weggelassen werden.

Man kann bekanntlich eine Klasse von einer Oberklasse mit "extends" ableiten, ein Interface wird dagegen mit dem Schlüsselwort "implements" implementiert. Beispiel, "implements"

Datei "Shape.java"

import java.awt.*;

//-------------------------------------------------------------- abstract class Shape implements Drawable { private int x, y;

int getX() { return x; } int getY() { return y; }

Shape(int x, int y) {this.x = x; this.y = y;}

// public void display(Graphics g, Color c)

void draw(Graphics g) {display(g, FG_COLOR);} void erase(Graphics g) {display(g, BG_COLOR);} ... }

Page 101: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 101

//-------------------------------------------------------------- class Circle extends Shape { ... public void display(Graphics g, Color c) { ... } }

//-------------------------------------------------------------- class Rect extends Shape { ... public void display(Graphics g, Color c) { ... } }

− Eine Klasse, die ein Interface implementiert, muss alle abstrakten Methoden des Interface überschreiben. Andernfalls wird sie wie "Shape" zur abstrakten Klasse ("abstract") oder der Compiler meldet einen Fehler.

− Eine Klasse kann nur von einer Oberklasse abgeleitet werden. Aber eine Klasse kann nicht nur eine, sondern beliebig viele Interfaces implementieren. Auf der Ebene von Interfaces ist also Mehrfachvererbung möglich.

− Interfaces bieten ein elegantes Mittel zur Prüfung, ob der Anwender bei Parameterübergaben den richtigen Typ übergeben hat.

In der Java-Klassenbibliothek werden eine Reihe von Interfaces definiert und implementiert. Im folgenden Abschnitt wird z.B. das Interface "Cloneable" zum "Klonen" von Objekten ein-gesetzt. Weitergehende Erläuterungen zu Schnittstellen sind z.B. in [1] zu finden.

6.3 Das Interface Cloneable

Klonen bedeutet nichts anderes, als eine exakte Kopie von etwas schon Existierendem zu erstellen. Wenn ein Objekt geklont wird, erwartet man, dass man eine Referenz auf ein neues Objekt bekommt, dessen Datenfelder die gleichen Werte haben, wie das Originalobjekt. Die bloße Zuweisung von Referenzen c2 = c1 leistet dies nicht. Um eine echte Kopie von Objekten einer Klasse zu bekommen muss man zwei Dinge tun: − Das Interface Cloneable implementiert. − Die Methode clone() der Klasse Object überschreiben. Diese Teile sind im nachfolgenden Beispiel "Clone 1" durch Fettdruck hervorgehoben. Die Klasse Circle implementiert das Interface Cloneable und enthält eine public-Methode clone(). In clone() wird der Aufruf an die Oberklasse, also an die Klasse Object weitergeleitet. Da die Klasse Circle das Interface Cloneable implementiert, sollte die CloneNotSupportedException nie auftreten. Die Aufgabe der Methode clone() der Klasse Object besteht darin, eine Eins-zu-Eins-Kopie des Objektes zu erstellen, für das sie aufgerufen wird. Beispiel, Clone 1

class Circle implements Cloneable { int x = 0; int y = 0; int r = 0; Circle(int x, int y, int r) {

Page 102: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 102

this.x = x; this.y = y; this.r = r; } void display() { System.out.println("x=" + x + ", y=" + y + ", r=" + r); } public Object clone() throws CloneNotSupportedException { // mit super.clone() wird die clone()-Methode

// der Klasse Object aufgerufen return super.clone();

}

} public class Clone1 { public static void main(String[] args) throws CloneNotSupportedException { Circle c1 = new Circle(10,10,10); Circle c2 = c1; c2.x = 20; c2.y = 20; c2.r = 20; c1.display(); c2.display(); c1 = new Circle(10,10,10); Circle c3 = (Circle) c1.clone(); c3.x = 30; c3.y = 30; c3.r = 30; c1.display(); c3.display(); } }

Auf der Konsole: x=20, y=20, r=20 x=20, y=20, r=20 x=10, y=10, r=10 x=30, y=30, r=30

Man erkennt an der Ausgabe, dass nach der bloßen Zuweisung c2 = c1 Änderungen an der Kopie c2 auch das Original c1 verändern, während nach c3 = (Circle) c1.clone() Änderungen an der Kopie c3 das Original c1 unverändert lassen. Es ist noch Folgendes zu bemerken. Man könnte vermuten, dass die Deklaration der clone()-Methode in dem Interface Cloneable enthalten ist. Das ist aber nicht der Fall, das Interface Cloneable hat einen leeren Rumpf: public interface Cloneable { }

Page 103: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 103

Was gewinnt man dann durch das Implementieren des Interface Cloneable? Das Kompilieren der Klasse Circle wäre auch möglich, wenn die clone()-Methode der Klasse Object in der Klasse Circle nicht überschrieben würde. Aber die clone()-Methode der Klasse Object hat nur den Zugriffsmodifikator protected, so dass der Aufruf c1.clone() in main() nicht möglich ist. Durch das Überschreiben in der Klasse Circle wird die Sichtbarkeit der clone()-Methode auf public angehoben. Das Implementieren des Interface Cloneable ist aber ebenfalls notwendig. Lässt man es weg, so lässt sich das Programm zwar compilieren, der Aufruf super.clone() wirft dann aber zur Laufzeit eine CloneNotSupportedException aus. Das Interface Cloneable ist ein so genanntes Marker-Interface. Die Klasse gibt damit an, dass ihre Objekte kopierbar sind. Man kann auf diese Weise verhindern, dass Objekte von Klassen kopiert werden, für die das gar nicht vorgesehen ist. Im vorausgegangenen Programm "Clone 1" war es ausreichend, in der Methode clone() der Klasse Circle einfach die Methode clone() der Klasse Object aufzurufen. Die Methode clone() der Klasse Object erzeugt dann eine Eins-zu-Eins-Kopie von allen Datenfeldern. Sobald die Datenfelder des Objekts nicht mehr nur aus einfachen Datentypen bestehen, sondern auch Referenzen umfassen, reicht obige Vorgehensweise aber nicht mehr aus. Denn die Methode clone() der Klasse Objekt erzeugt dann nur eine Kopie der jeweiligen Referenz, also lediglich eine flache Kopie. Im nachfolgenden Beispielprogramm "Clone 2" ist das deutlich zu sehen. Eine Membervariable der Klasse Circle ist jetzt von dem Referenztyp Point, welcher in dem Paket java.awt deklariert ist, und Punkte in der Ebene beschreibt. Beispiel, Clone 2 import java.awt.Point; class Circle implements Cloneable { Point p; int r; Circle(int x, int y, int r) { this.p = new Point(x,y); this.r = r; } void display() { System.out.println("x=" + p.x + ", y=" + p.y + ", r=" + r); } public Object clone () throws CloneNotSupportedException { // mit super.clone() wird die clone()-Methode // der Klasse Object aufgerufen. Das erzeugt hier // zunächst lediglich eine flache Kopie return super.clone(); } } public class Clone2 { public static void main(String[] args)

Page 104: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 104

throws CloneNotSupportedException { Circle c1 = new Circle(10,10,10); Circle c2 = (Circle) c1.clone(); c2.p.x = 30; c2.p.y = 30; c2.r = 30; c1.display(); c2.display(); } }

Auf der Konsole: x=30, y=30, r=10 x=30, y=30, r=30

Änderungen an der Instanzvariable p des Objektes c2 verändern auch das Original c1 an der entsprechenden Stelle. Man muss die clone()-Methode der Klasse Circle so erweitern, dass das in der Classe Cirlcle enthaltenen Teilobjekt des Typs Point echt mit kopiert (geklont) wird. Auf diese Weise erhält man dann eine tiefe Kopie des Circle-Objekts. public Object clone () throws CloneNotSupportedException { // mit super.clone() wird die clone()-Methode // der Klasse Object aufgerufen. Das erzeugt // zunächst eine flache Kopie Circle temp = (Circle) super.clone(); // dann Erweiterung zur tiefe Kopie

temp.p = (Point) p.clone();

return temp;

}

Mit der so geänderten clone()-Methode in der Klasse Circle liefert das Programm "Clone 2" auf der Konsole: x=10, y=10, r=10 x=30, y=30, r=30

Das nachfolgende Beispiel "Clone 3" zeigt Beispiel schließlich noch, wie Objekte einer Vererbungshierarchie zu klonen sind. Man hat lediglich in jeder Stufe der Hierarchie zu entscheiden, ob eine tiefe Kopie notwendig ist. Dies ist immer dann erforderlich, wenn die entsprechende Unterklasse Membervariablen hat, die von Referenztyp sind. In diesem Fall müssen die entsprechenden Membervariablen tief kopiert werden. Beispiel, Clone 3 import java.awt.Point; class OnePoint implements Cloneable { Point p1; OnePoint(int x, int y) {

Page 105: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 105

this.p1 = new Point(x,y); } void display() { System.out.println("x=" + p1.x + ", y=" + p1.y); } public Object clone () throws CloneNotSupportedException { OnePoint temp = (OnePoint) super.clone(); temp.p1 = (Point) p1.clone(); return temp; } } class TwoPoints extends OnePoint { Point p2; TwoPoints(int x1, int y1, int x2, int y2) { super(x1,y1); p2 = new Point(x2,y2); } void display() { System.out.println("x1=" + p1.x + ", y1=" + p1.y + ", x2=" + p2.x + ", y2=" + p2.y); } public Object clone () throws CloneNotSupportedException { TwoPoints temp = (TwoPoints) super.clone(); temp.p2 = (Point) p2.clone(); return temp; } } public class Clone3 { public static void main(String[] args) throws CloneNotSupportedException { TwoPoints t1 = new TwoPoints(10,10,10,10); TwoPoints t2 = (TwoPoints) t1.clone(); t2.p1.x = 30; t2.p1.y = 30; t2.p2.x = 30; t2.p2.y = 30; t1.display(); t2.display(); } }

Page 106: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 106

Auf der Konsole: x1=10, y1=10, x2=10, y2=10 x1=30, y1=30, x2=30, y2=30

6.4 Das generische Interface Comparable<T>

Als Beispiel für ein generisches Interface betrachten wir das Interface Comparable<T>. Dieses Interface kann von jeder Klasse implementiert werden und ermöglicht dann, dass Arrays, bestehend aus Referenzen auf Objekte dieser Klasse durch die Klassenmethode public static void sort (Object[] a)

der Klasse Arrays aus dem Packet java.util sortiert werden können. Die Implementierung des generischen Interface Comparable<T> stellt dabei sicher, dass die Objekte eine Vergleichsoperation unterstützen. Das generische Interface Comparable<T> hat den Aufbau public interface Comparable<T> { public int compareTo (T o); }

Dabei werden bei dem Aufruf a.compareTo(b) folgende Rückgabewerte erwartet: − kleiner Null (z.B. -1), wenn a < b, − 0, wenn a == b, − größer Null (z.B. +1), wenn a > b ist. Nachfolgend ein Beispiel hierzu, bei dem mechanische Artikel erfasst und sortiert werden. Die Klasse Artikle hat zwei Membervariablen artNr und name und implementiert das Interface Comparable<T>. Beispiel, Vergleich import java.util.*; class Artikel implements Comparable<Artikel> { private Integer artNr; private String name; public Artikel (Integer artNr, String name) { this.artNr = artNr; this.name = name; } public int compareTo (Artikel artikel) {

// Die Methode compareToIgnoreCase() ist in der Klasse // String implementiert und liefert einen lexikographischen

// Vergleich beider Strings ohne Brücksichtigung von

Page 107: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 107

// Groß- und Kleinschreibung

return name.compareToIgnoreCase (artikel.name);

}

// Überschreiben der toString()-Methode, um die String- // repräsentation des Objektes ausgeben zu können. public String toString() { return (artNr + " " + name); } } public class Vergleich { public static void main (String[] args) { Artikel[] arr = new Artikel [4]; arr [0] = new Artikel (1000, "Mutter"); arr [1] = new Artikel (1001, "Dichtungsring"); arr [2] = new Artikel (1002, "Abstreifring"); arr [3] = new Artikel (1003, "montierbarer Zackenring"); Arrays.sort (arr); for (Artikel artikel : arr) System.out.println (artikel); } }

Auf der Konsole 1002 Abstreifring 1001 Dichtungsring 1003 montierbarer Zackenring 1000 Mutter

6.5 Ereignisbehandlung Die Ereignisbehandlung basiert auf dem Konzept der Ereignisempfänger (Event Listener). Jedes Objekt, das über Ereignisse benachrichtigt werden kann, ist ein Ereignisempfänger. Eine Ereignisquelle (Event Source) verwaltet eine Liste von Empfängern, die über Ereignisse zu benachrichtigen sind und stellt Methoden zur Verfügung, mit denen sich Empfänger selbst in diese Liste aufnehmen oder sich wieder aus ihr löschen können. Beispiele: addMouseListener(MouseListener);

removeMouseListener(MouseListener);

Wenn dann ein Ereignis eintritt, benachrichtigt die Quelle alle Empfänger, die sich in ihre Liste eingetragen haben. Ein Empfänger wird durch Aufruf einer dem jeweiligen Ereignis zugeordneten Methode benachrichtigt. Als Folge dieser Vorgehensweise müssen Ereignis-empfänger alle zugehörigen Methoden implementieren, ein "MouseListener" zum Beispiel alle fünf in Tabelle 6.1 gegebenen Methoden. Das wird dadurch erzwungen, dass im Interface "MouseListener" alle fünf Methoden als abstrakte Methoden aufgeführt sind.

Page 108: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 108

Tabelle 6.1 MouseListener und zugehörige Methoden Listener-Interface Methoden Auslösende Aktion MouseListener mouseClicked Eine Maustaste wurde gedrückt und wieder

losgelassen mouseEntered Der Mauszeiger "betritt" die Komponente mouseExited Der Mauszeiger verlässt die Komponente mousePressed Eine Maustaste wurde gedrückt mouseReleased Eine Maustaste wurde losgelassen Lösung 1: Implementieren des Interface

Im Beispiel "Event1" wird das Interface "MosueListener" imple-mentiert. Das Programm gibt einen Zählerstand aus (Bild 6.2), der inkrementiert wird, wenn der Mauszeiger das Fenster "betritt".

Beispiel, Event1 import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class Event1 extends JPanel implements MouseListener{ private int count = 0;

Event1() { addMouseListener(this); }

public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Counter: " + count, 20, 20); }

public static void main(String[] args) { JFrame window = new JFrame("Event1"); window.setSize(160, 100); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new Event1()); window.setVisible(true); }

public void mouseEntered(MouseEvent me) { count++; repaint(); }

public void mouseClicked(MouseEvent me) {} public void mouseExited(MouseEvent me) {} public void mousePressed(MouseEvent me) {} public void mouseReleased(MouseEvent me) {} }

addMouseListener(this); Die Klasse "Event1" meldet sich selbst als Ereignisempfänger an. public void mouseClicked(MouseEvent me) {} ... public void mouseReleased(MouseEvent me) {}

Bild 6.2 Event1

Page 109: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 109

Die leeren Methoden werden eigentlich nicht benötigt, es müssen aber alle fünf Methoden des Interface überschrieben werden. Lösung 2: Adapterklasse und Innere Klasse

Mit Adapterklassen (Tabelle 6.2) lässt sich verhindern, dass Ereignisempfänger leere Methoden enthalten, die für die Anwendung eigentlich unnötig sind. In Java gibt es Adapter-klassen für alle Listener-Interfaces mit mehr als einer Methode. Tabelle 6.2 Einige Event-Listener und die zugehörigen Adapterklassen Listener-Interface Adapterklasse Methoden MouseListener MouseAdapter mouseClicked, mouseEntered, mouseExit,

mousePressed, mouseReleased MouseMotionListener MouseMotionAdapter mouseDragged, mouseMoved KeyListener KeyAdapter keyPressed, keyReleased, keyTyped

Eine Adapterklasse ist eine abstrakte Klasse, die das zugehörige Listener-Interface mit leeren Methoden implementiert. Die Methoden sind zwar leer, aber nicht abstrakt.

Klassen, die von einer Adapterklasse abgeleitet sind, brauchen deshalb nur noch die in der Anwendung wirklich benötigten Methoden zu implementieren, sie überschreiben für diese Fälle also die leeren Methoden der Adapterklasse.

Da in Java Mehrfachvererbung nicht zulässig ist, wird im folgenden Beispiel eine innere Klasse eingesetzt. Die Vorgehensweise ist aus vielen früheren Beispielen schon bekannt.

Beispiel, Event2

import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class Event2 extends JPanel { private int count = 0;

Event2() { addMouseListener(new MyMouseListener()); }

public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Counter: " + count, 20, 20); }

public static void main(String[] args) { JFrame window = new JFrame("Event2"); window.setSize(160, 100); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new Event2()); window.setVisible(true); } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyMouseListener extends MouseAdapter { public void mouseEntered(MouseEvent me) { count++; repaint(); } } }

Page 110: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 110

addMouseListener(new MyMouseListener());

Eine Instanz von "MyMouseListener" wird angelegt und als Ereignisempfänger angemeldet. class MyMouseListener extends MouseAdapter { public void mouseEntered(MouseEvent me) { count++; repaint(); } }

Die innere Klasse überschreibt die Methode "mouseEntered" der Adapterklasse. Lösung 3: Adapterklasse und anonyme lokale Klasse

Man kann eine lokale Klasse deklarieren, ohne ihr einen Namen zu geben. Im Programm "Event3" wird eine derartige anonyme lokale Klasse eingesetzt. Da anonyme Klassen keinen Namen haben, müssen sie gleich bei der Definition instanziiert werden.

Beispiel, Event3 import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class Event3 extends JPanel { private int count = 0;

Event3() { addMouseListener( new MouseAdapter() { public void mouseEntered(MouseEvent me) { count++; repaint(); } } ); }

public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Counter: " + count, 20, 20); }

public static void main(String[] args) { JFrame window = new JFrame("Event3"); window.setSize(160, 100); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new Event3()); window.setVisible(true); } }

Im Konstruktor wird eine Kurzschreibweise eingesetzt, die Bild 6.3 erläutert. Der Compiler erzeugt hier also ein Objekt einer anonymen Klasse, die von "MouseAdapter" abgeleitet worden ist. Zu beachten ist, dass bei anonymen Klassen die Definition der Klasse und ihre Instanziierung in einer Anweisung erfolgen.

Page 111: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

6 OOP II : Polymorphie, Abstrakte Klassen und Interfaces 111

addMouseListener(new MyMouseListener());

zusammen mit der Definition class MyMouseListener extends MouseAdapter { public void mouseEntered(MouseEvent me) { count++; repaint(); } }

wird ersetzt durch: addMouseListener( new MouseAdapter() { public void mouseEntered(MouseEvent me) { count++; repaint(); } } );

Bild 6.3 Verwendung einer anonymen lokalen Klasse

Page 112: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads Für Animationen muss eine Folge von einzelnen Bildern ausgegeben werden. Dazu kann man Timer (Zeitgeber) oder Threads (Programmfäden) einsetzen.

7.1 Timer

Im folgenden Programm wird der aktuelle Stand eines Zählers fortlaufend ausgegeben. Mit den Maustasten lässt sich der Zähler anhalten und wieder starten. Ein Timer spricht hier alle 500 ms seinen Ereignisempfänger an. Es wird dann die Methode "actionPerformed" des Inter-face "ActionListener" ausgeführt (Tabelle 7.1). Tabelle 7.1 Action Listener und zugehörige Methode Listener-Interface Methode Auslösende Aktion ActionListener actionPerfomed Ein Ereignis hat stattgefunden, eine Timerverzögerung

ist z.B. abgelaufen Beispiel, Counter import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Counter extends JPanel implements ActionListener { private Timer timer; private int number = 0; Counter() { addMouseListener(new MyMouseListener()); // Timer(int delay, ActionListener a), delay in ms timer = new Timer(500, this); timer.setInitialDelay(0); timer.start(); } public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Counter: " + number, 20, 40); } public static void main(String[] args) { JFrame window = new JFrame("Counter"); window.setSize(260, 160); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new Counter()); window.setVisible(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public void actionPerformed(ActionEvent e){ number++; repaint(); }

Page 113: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 113

class MyMouseListener extends MouseAdapter { public void mousePressed(MouseEvent me) { if(timer.isRunning()) timer.stop(); else timer.start(); } } }

Das Programm gibt das Fenster in Bild 7.1 aus.

timer = new Timer(500, this);

Die Anweisung instanziiert einen Timer mit einer Verzögerung von 500 ms und legt das aktuelle Objekt (this) als ActionListener fest.

timer.setInitialDelay(0);

Mit der Methode lässt sich die Verzögerung für die erste Ausführung von "actionPer-formed" angeben. Ohne den Aufruf würde "actionPerformed" nach der an den Kon-struktor übergebenen Verzögerung zum ersten Mal ausgeführt, hier also nach 500 ms.

if(timer.isRunning()) timer.stop(); else timer.start();

Die Anweisungen ändern den gegenwärtigen Zustand des Timers. Ein laufender Timer (run-ning) wird gestoppt und umgekehrt.

Aufgabe 7.1

Schreiben Sie ein Programm "Clock", das die laufende Uhrzeit auf der Konsole und zusätzlich das aktuelle Datum und die laufende Uhrzeit in einem Fenster ausgibt (Bild 7.2). Auf der Konsole ... 5:41:19 5:41:20 5:41:21 ...

Bild 7.2 Ausgabe von "Clock"

Der folgende Programmausschnitt zeigt, wie man Instanzen der Klassen "GregorianCalendar" und "Date" zur Ausgabe von Zeit und Datum einsetzen kann.

... import java.util.*; // For GregorianCalendar and Date ...

// Get a calendar using the default time zone GregorianCalendar cal = new GregorianCalendar();

// Print the current time, GregorianCalendar is a // subclass of Calendar

Bild 7.1 Counter

Page 114: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 114

System.out.println(cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND)); // Copy date and time to a Date object and display it Date date = cal.getTime(); g.drawString("Current date and time: " + date, 10, 25); ...

Im folgenden Programm werden zwei Timer verwendet. − Timer "t1" führt zum Aufruf der Methode "addString",

die die Zeichenkette "Two timers" mit zufälliger Position und Farbe ausgibt (Bild 7.3).

− Timer "t2" führt zum Aufruf von "repaint" und hat den Aufruf von "paintComponent" zur Folge.

Beispiel, TwoTimers import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TwoTimers extends JPanel { private Font font = new Font("Serif", Font.BOLD, 20); TwoTimers() { setBackground(Color.WHITE); Timer t1 = new Timer( 100,new Timer1()); Timer t2 = new Timer(2000,new Timer2()); t1.start(); t2.start(); } public void paintComponent(Graphics g) { super.paintComponent(g); } void addString(Graphics g) { int x = -50 + (int) (Math.random() * (getSize().width + 40)); int y = (int) (Math.random() * (getSize().height + 20)); float hue = (float) Math.random(); // hue = Farbton g.setFont(font); g.setColor(Color.getHSBColor(hue, 1.0F, 1.0F)); g.drawString("Two timers", x, y); } public static void main(String[] args) { JFrame window = new JFrame("Two timers"); window.setSize(240, 200); window.setLocation(100, 100); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(new TwoTimers()); window.setVisible(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class Timer1 implements ActionListener {

Bild 7.3 Zwei Timer

Page 115: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 115

public void actionPerformed(ActionEvent e) { addString(getGraphics()); } } class Timer2 implements ActionListener { public void actionPerformed(ActionEvent e){ repaint(); } } }

7.2 Threads und das Interface Runnable

Ein Thread ist ein "Programmfaden". Multithreading ermöglicht es, mehrere Programmfäden gleichzeitig oder quasi gleichzeitig auszuführen. − In Einprozessorsystemen ist nur quasi gleichzeitige Abarbeitung möglich. Das Betriebs-

system teilt dazu den Threads nacheinander den Prozessor in Zeitscheiben zu. − In Mehrprozessorsystemen können dagegen mehrere Threads tatsächlich gleichzeitig

ablaufen.

Threads werden durch Erweitern der Klasse "Thread" oder durch Implementieren des Interface "Runnable" realisiert.

Beispiel, Thread1 public class Thread1 { public static void main(String[] args) { MyThread alpha = new MyThread(" Thread Alpha"); MyThread beta = new MyThread(" Thread Beta"); alpha.start(); beta.start(); } } class MyThread extends Thread { private String s; MyThread(String s) { this.s = s; } public void run() { for(int i = 0; i < 5; i++) { System.out.println(i + s); try { // Sleep for 1 ms sleep(1); } catch (InterruptedException e) {} } } } alpha.start(); beta.start();

Der Programmfäden "alpha" und "beta" werden gestartet und laufen nun quasi gleichzeitig ab.

Auf der Konsole 0 Thread Alpha 0 Thread Beta 1 Thread Alpha 1 Thread Beta 2 Thread Beta 2 Thread Alpha 3 Thread Alpha 3 Thread Beta 4 Thread Alpha 4 Thread Beta

Page 116: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 116

class MyThread extends Thread { ... public void run() { ...

Die Methode "run" wird beim Start eines Thread aufgerufen. Sie enthält den Programmcode des Thread. Ein Thread beendet sich selbst, wenn "run" abgearbeitet worden ist. try { sleep(1); } catch (InterruptedException e) {}

Mit der Methode "sleep" kann man einen Programmfaden für eine vorgebbare Anzahl von Millisekunden pausieren lassen. Die Konsolenausgabe zeigt, dass die beiden Programmfäden tatsächlich quasi gleichzeitig ablaufen. Man erkennt außerdem, dass das Ende von "main" nicht zum Stopp der beiden Threads führt. Eine Java-Applikation ist erst dann beendet, wenn der letzte Thread abgeschlossen worden ist4.

Aufgabe 7.2

Schreiben Sie ein Programm "Thread2". Das Programm soll sich von "Thread1" dadurch unterscheiden, dass nur ein zusätzlicher Thread gestartet wird und die Konsolenausgaben in "main" und in der Methode "run" des Threads dann quasi gleichzeitig erfolgen.

Da Java Mehrfachvererbung nicht unterstützt, kann in dem nachfolgenden Applet die von JPanel abgeleitete Klasse ACPanel nicht zusätzlich noch von "Thread" abgeleitet werden. Stattdessen muss das Interface "Runnable" implementiert werden, das als einzige Deklaration "public abstract void run()" enthält. Die abstrakte Methode "run" ist dann zu überschreiben. Beispiel, AppletCounter2 import java.awt.*; import javax.swing.*; public class AppletCounter2 extends JApplet { private Thread countThread = null; private ACPanel acPanel; public void init() { acPanel = new ACPanel(); getContentPane().add(acPanel); } public void start() { countThread = new Thread(acPanel); countThread.start(); }

4 Sogenannte Hintergrund-Threads oder Dämonen werden beim Beenden von "main" gestoppt, vgl. z.B. [1].

Page 117: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 117

public void stop() { acPanel.beenden(); } public void destroy() { acPanel.beenden(); } } class ACPanel extends JPanel implements Runnable { private int num = 0; private boolean running = false; public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Value: " + num++, 60, 40); } public void run() { num = 0; running = true; while(running == true) { repaint(); try { Thread.sleep(500); } catch(InterruptedException e) { } } System.out.println("Thread Terminated!"); } public void beenden() { running = false; } }

Zum Abschluss noch ein typisches Beispiel für die Verwendung von Threads. In dem nachfolgenden Applet läuft im Hintergrund eine Schrift durchs Bild, während man parallel dazu im Vordergrund mit der Maus einen Kreis immer wieder neu positionieren kann. Wenn das Applet unsichtbar wird oder geschlossen wird, wird der Thread mit der Methode interrupt() gestoppt. Beispiel, MouseAndThread02 import java.awt.*; import java.awt.event.*; // For MouseEvent import javax.swing.*; public class MouseAndThread02 extends JApplet { Thread laufThread; MouseAndThreadPanel mtPanel;

Bild 7.4 AppletCounter1

Page 118: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 118

public void init() { mtPanel = new MouseAndThreadPanel(); getContentPane().add(mtPanel); } public void start() { laufThread = new Thread(mtPanel); laufThread.start(); } public void stop() { laufThread.interrupt(); } public void destroy() { laufThread.interrupt(); } } //---------------------------------------------------- class MouseAndThreadPanel extends JPanel implements Runnable { private static final int R = 40; private static final Color BG_COLOR = Color.WHITE; private static final Color FG_COLOR = Color.GREEN; private static final Color TXT_COLOR = Color.RED; private int x = 40, y = 40; // Center of circle // Variablen für Laufschrift String text; String hello; int lengthText, // Laenge des Textes xpos, // x-Position des Textes ypos, // y-Position des Textes xmax; // Breite des Fensters Font fontText; Font fontHello; int fs; MouseAndThreadPanel() { // Add MyMouseListener and MouseMotionListener // to receive mouse motion events addMouseListener(new MyMouseListener()); addMouseMotionListener(new MyMouseMotionListener()); setBackground(BG_COLOR); text = " ... Java ... "; fs = 28; fontText = new Font("SansSerif", Font.BOLD, fs); FontMetrics fm = getFontMetrics(fontText); lengthText = fm.stringWidth(text); ypos = (int) (fs*1.2) ; }

Page 119: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 119

public void paintComponent(Graphics g) { super.paintComponent(g); // Update if window size has been changed if (xmax != getSize().width) { xmax = getSize().width; } g.setColor(TXT_COLOR); g.setFont(fontText); g.drawString(text, xpos , ypos); draw(g); } void display(Graphics g, Color c) { g.setColor(c); g.drawOval(x-R, y-R, R+R, R+R); } void draw(Graphics g) { display(g, FG_COLOR); } public void run() { Graphics g = getGraphics(); g.setFont(fontText); xmax = getSize().width; xpos = xmax; while(true) { xpos--; if(xpos < -lengthText) { xpos = xmax ; } repaint(); try { Thread.sleep(20); } catch(InterruptedException e) { System.out.println("Thread Interrupted!"); return; } } } //---------------------------------------------------- class MyMouseListener extends MouseAdapter { public void mousePressed(MouseEvent me) { x = me.getX(); y = me.getY(); repaint(); } } //---------------------------------------------------- class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent me) { x = me.getX(); y = me.getY(); repaint(); } } }

Page 120: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

7 Timer und Threads 120

Die Ausgabe dieses Applets ist in der nachfolgenden Abbildung 7.5 zu sehen. Weitergehende Erläuterungen zu Threads, insbesondere zu Threadgruppen, Threadprioritäten und Synchroni-sationsproblemen, sind z.B. in [1] zu finden.

Aufgabe 7.3

Schreiben Sie ein Applet "Lines", das wie ein Bildschirmschoner ein farbiges Linienbündel aus-gibt (Bild 7.5). Das Linienbündel läuft im Uhr-zeigersinn auf einer Spiralbahn um ein Zentrum in der Fenstermitte. Der Umlaufradius schrumpft bis zu einer Untergrenze und wächst dann wieder bis zu einer Obergrenze.

7.3 Übungsaufgaben Übungsaufgabe 7.1

Schreiben Sie ein Applet "Laufschrift", das eine Textnachricht als Laufschrift auf dem Bild-schirm darstellt. Lesen Sie den auszugebenden Text aus der HTML Datei ein. a) Verwenden Sie in Ihrer Lösung einen Timer. b) Verwenden Sie in Ihrer Lösung das Interface Runnable.

Bild 7.6 Applet Lines

Bild 7.5 Applet MouseAndThread02

Page 121: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten

In diesem Abschnitt wird eine Auswahl von Swing-Komponenten vorgestellt. Mit diesen Komponenten lassen sich übersichtliche und intuitiv einsetzbare Schnittstellen zum Anwender programmieren.

8.1 Übersicht über die Swing-Komponenten

Die folgende Übersicht stammt aus dem Java Tutorial [4]. Dort sind auch weitergehende Erläuterungen zu allen Swing-Komponenten zu finden.

Top-Level Containers

Applet

Dialog

Frame

General-Purpose Containers

Panel

Scroll pane

Split pane

Tabbed pane

Tool bar

Special-Purpose Containers

Internal frame

Layered pane

Page 122: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 122

Root pane

Basic Controls

Buttons

Combo box

Text fields

Menu

Slider

List

Uneditable Information Displays

Label

Progress bar

Tool tip

Editable Displays of Formatted Information

Color chooser

File chooser

Page 123: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 123

Table

Text

Tree In der Regel wird man die genaue Platzierung der Komponenten im jeweiligen Fenster einem "Layout-Manger" überlassen. Ein Layout-Manager erhält Vorgaben und passt dann Größe und genaue Platzierung der Dialogelemente der jeweiligen Fenstergröße an. Man kann für die Dialogelemente aber auch feste Positionen und Größen angeben.

8.2 JButton und JLabel

Ein Button (JButton) ist eine beschriftete Schaltfläche. Wenn man einen Button anklickt, wird die aus dem vorausgehenden Abschnitt schon bekannte Methode "ActionPerformed" des Interface "ActionListener" ausgeführt.

Ein Label (JLabel) dient zur Ausgabe eines Textes und reagiert nicht auf Benutzereingaben. Der ausgegebene Text lässt sich während der Programmausführung ändern.

Im folgenden Programm wird kein Layout-Manager eingesetzt, die Komponenten werden also fest platziert. Beispiel, Layout1 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*;

public class Layout1 extends JFrame implements ActionListener { final private String[] BTXT = {"Pass", "Back", "Back to OS"}; final private JLabel lbl = new JLabel("Start", JLabel.CENTER);

Layout1() { Container con = getContentPane();

// public void setLayout(LayoutManager mgr) // mgr -> layout manager or null con.setLayout(null);

// public void setBounds(int topLeftX, int topLeftY, // int width, int height) lbl.setBounds(12, 8, 248, 40);

// public void setBorder(Border border) // border -> border to be drawn for this component lbl.setBorder(new LineBorder(Color.BLACK)); con.add(lbl);

for(int i = 0; i < BTXT.length; i++) { JButton btn = new JButton(BTXT[i]); btn.setBounds(10+85*i, 55, 80, 25);

Page 124: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 124

Bild 8.1 Feste Koordinaten

con.add(btn); btn.addActionListener(this); } }

public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd == BTXT[2]) System.exit(0); lbl.setText(cmd); }

public static void main(String[] args) { JFrame window = new Layout1(); window.setTitle("Layout 1"); window.setSize(280, 110); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.1 zeigt das vom Programm ausgegebene Fenster. Der Button "Back to OS" beendet das Programm. Die beiden anderen Schaltflächen füh-ren hier nur dazu, dass die jeweilige Beschriftung im Label ausgegeben wird. Da die Komponenten vorgegebene Koordinaten haben, passen sich ihre Positionen Änderungen der Fenstergröße nicht an.

Die Vorgabe fester Koordinaten ist in der Regel keine gute Idee. Man sollte die Platzierung vielmehr einem Layout-Manager überlassen.

8.3 Layout-Manager

Es stehen sechs Layout-Manager mit unterschiedlichen Platzierungsstrategien zur Verfügung. Im Folgenden werden vier der Layout-Manager erläutert, eine vollständigere Beschreibung ist z. B. in [1] zu finden. − FlowLayout ordnet Komponenten nebeneinander in einer Zeile an. − BorderLayout verteilt die Komponenten auf die vier Randbereiche und den Mittelbereich

eines Fensters. − GridLayout positioniert die Komponenten in einem rechteckigen Gitter, dessen Zeilen-

und Spaltenzahl frei wählbar ist. − BoxLayout ordnet die Komponenten in einer horizontalen oder in einer vertikalen Leiste

an.

FlowLayout FlowLayout platziert die Dialogelemente ähnlich zu Textzeilen. Wenn keine weiteren Kom-ponenten in die Zeile passen, wird mit der nächsten Zeile fortgefahren. In der Voreinstellung werden die Komponenten in den Zeilen zentriert ausgegeben.

Page 125: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 125

Beispiel, Layout2 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*;

public class Layout2 extends JFrame implements ActionListener { final private String[] BTXT = {"Pass", "Back", "Back to OS"}; final private JLabel lbl = new JLabel("Start", JLabel.CENTER);

Layout2() { Container con = getContentPane();

// FlowLayout() -> centered alignment and a default // 5-unit horizontal and vertical gap // FlowLayout(int align) -> align = FlowLayout.LEFT, RIGHT // or CENTER, 5-unit horizontal and vertical gap // FlowLayout(int align, int hgap, int vgap) con.setLayout(new FlowLayout());

lbl.setBorder(new LineBorder(Color.BLACK)); con.add(lbl);

for(int i = 0; i < BTXT.length; i++) { JButton btn = new JButton(BTXT[i]); con.add(btn); btn.addActionListener(this); } }

public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd == BTXT[2]) System.exit(0); lbl.setText(cmd); }

public static void main(String[] args) { JFrame window = new Layout2(); window.setTitle("Layout 2"); window.pack();

window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.2 zeigt das vom Programm ausgegebene Fenster. Man erkennt, dass sich die Größe der Komponenten nach dem Platzbedarf der Beschriftung richtet.

Man kann die bevorzugte Komponentengröße vorgeben. Der folgende Programmausschnitt zeigt die Vorgehensweise. ...

Layout2() { Container con = getContentPane();

Bild 8.2 FlowLayout

Page 126: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 126

con.setLayout(new FlowLayout());

lbl.setPreferredSize(new Dimension(248, 40)); lbl.setBorder(new LineBorder(Color.BLACK)); con.add(lbl); for(int i = 0; i < BTXT.length; i++) { JButton btn = new JButton(BTXT[i]); btn.setPreferredSize(new Dimension(80, 25));

con.add(btn); btn.addActionListener(this); } }

...

public static void main(String[] args) { JFrame window = new Layout2(); window.setTitle("Layout 2"); window.setSize(280, 110);

window.setResizable(false);

window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.3 zeigt das Fenster, das nach diesen Änderungen ausgegeben wird. Der Aufruf von "setResizable(false)" führt dazu, dass sich die Fenstergröße nicht mehr ändern lässt. BorderLayout Mit BorderLayout lassen sich Dialogelemente an den vier Rändern ("BorderLayout. EAST", "BorderLayout.NORTH", "BorderLayout.WEST", "BorderLayout.SOUTH") und in der Mitte ("BorderLayout.CENTER") platzieren. Beispiel, Layout3 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Layout3 extends JFrame implements ActionListener { final private String[] BTXT = {"Pass", "Back", "Back to OS"}; final private JLabel lbl = new JLabel(" Start ", JLabel.CENTER); final private String [] BLOC = {BorderLayout.WEST, BorderLayout.EAST, BorderLayout.SOUTH}; Layout3() { Container con = getContentPane(); // BorderLayout() -> no gaps between components

Bild 8.3 Vorgegebene Größe

Page 127: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 127

// BorderLayout(int hgap, int vgap) -> layout with // the specified gaps between components con.setLayout(new BorderLayout()); con.add(lbl, BorderLayout.CENTER); for(int i = 0; i < BTXT.length; i++) { JButton btn = new JButton(BTXT[i]); con.add(btn, BLOC[i]); btn.addActionListener(this); } }

public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd == BTXT[2]) System.exit(0); lbl.setText(cmd); }

public static void main(String[] args) { JFrame window = new Layout3(); window.setTitle("Layout 3"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.4 zeigt das vom Programm ausgegebene Fenster. Wenn das Fenster vergrößert oder verkleinert wird, passen sich die Kom-ponenten dieser Änderung an. Komponenten an den vertikalen Rändern ändern dazu ihre Höhe, Komponenten an den horizontalen Rändern ihre Breite. Ist eine Komponente in der Mitte platziert, ändert sie sowohl Höhe als auch Breite.

GridLayout Mit GridLayout lassen sich Komponenten in einem Raster mit wählbarer Spalten- und Zeilenzahl anordnen. Alle Rasterplätze haben dabei ein- und dieselbe Größe. Die Komponenten werden in der obersten Zeile von links beginnend der Reihe nach platziert, dann in der zweiten Zeile, usw. Beispiel, Layout4 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Layout4 extends JFrame implements ActionListener { final private String[] BTXT = {"Pass", "Back", "Back to OS"}; final private JLabel lbl = new JLabel("Start", JLabel.CENTER); Layout4() { Container con = getContentPane();

Bild 8.4 BorderLayout

Page 128: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 128

// GridLayout() -> grid layout with a default of one // column per component, in a single row // GridLayout(int rows, int cols) -> grid layout with the // specified number of rows and columns // GridLayout(int rows, int cols, int hgap, int vgap) -> // Grid layout with the specified // number of rows and columns and gaps con.setLayout(new GridLayout(2,2)); con.add(lbl); for(int i = 0; i < BTXT.length; i++) { JButton btn = new JButton(BTXT[i]); con.add(btn); btn.addActionListener(this); } } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd == BTXT[2]) System.exit(0); lbl.setText(cmd); } public static void main(String[] args) { JFrame window = new Layout4(); window.setTitle("Layout 4"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.5 zeigt das vom Programm ausgegebene Fenster. Wenn das Fenster vergrößert oder verkleinert wird, passen sich die Komponenten diesen Änderungen an. Schachteln von Layout-Managern Zum Schachteln von Layout-Managern setzt man Objekte der Klasse "JPanel" ein. In diesen "Tafeln" platziert man Sublayouts, die dann zum Gesamtlayout zusammengefügt werden. Das folgende Beispiel zeigt die Vorgehensweise. Beispiel, Layout5 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Layout5 extends JFrame implements ActionListener { final private JLabel lbl = new JLabel(" Start ", JLabel.CENTER);

Bild 8.5 GridLayout

Page 129: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 129

final private int BNUM = 3; Layout5() { JPanel pnl1 = new JPanel(new GridLayout(BNUM, 1)); for(int i = 0; i < BNUM; i++) { JButton btn = new JButton("BV" + i); pnl1.add(btn); btn.addActionListener(this); } JPanel pnl2 = new JPanel(new GridLayout(1, BNUM)); for(int i = 0; i < BNUM; i++) { JButton btn = new JButton("BH" + (i+BNUM)); pnl2.add(btn); btn.addActionListener(this); } Container con = getContentPane(); // con.setLayout(new BorderLayout()); // Default layout con.add(BorderLayout.CENTER, lbl); con.add(BorderLayout.WEST, pnl1); con.add(BorderLayout.EAST, pnl2); } public void actionPerformed(ActionEvent e) { lbl.setText(e.getActionCommand()); } public static void main(String[] args) { JFrame window = new Layout5(); window.setTitle("Layout 5"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.6 zeigt das vom Programm ausgegebene Fenster. Auch hier passen sich die Komponenten Änderungen der Fenstergröße an.

Aufgabe 8.1

Schreiben Sie ein Programm "Layout6", das das in Bild 8.7 gegebene Fenster ausgibt. Die Kom-ponenten sollen sich Änderungen der Fenstergröße anpassen.

BoxLayout BoxLayout ordnet die Komponenten in einer horizontalen oder in einer vertikalen Leiste an. Dir Breite von Schaltflächen richtet sich dabei nach ihrer Beschriftung.

Bild 8.7 Fenster zur Aufgabe

Bild 8.6 Geschachtelte Layout-Manager

Page 130: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 130

Beispiel, Layout7 import java.awt.*; import javax.swing.*; public class Layout7 extends JFrame { Layout7() { JPanel pnlv = new JPanel(); // BoxLayout(Container target, int axis) // target - the container that needs to be laid out // axis - the axis to lay out components along. Can // be BoxLayout.X_AXIS or BoxLayout.Y_AXIS pnlv.setLayout(new BoxLayout(pnlv, BoxLayout.Y_AXIS)); for(int i = 0; i < 4; i++) pnlv.add(new JButton("BV " + i)); JPanel pnlh = new JPanel(); pnlh.setLayout(new BoxLayout(pnlh, BoxLayout.X_AXIS)); pnlh.add(new JButton("--- BH 0 ---")); for(int i = 1; i < 4; i++) pnlh.add(new JButton("BH " + i)); Container cp = getContentPane(); cp.add(BorderLayout.EAST, pnlv); cp.add(BorderLayout.SOUTH, pnlh); } public static void main(String[] args) { JFrame window = new Layout7(); window.setTitle("Layout 7"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.8 zeigt das vom Programm ausgegebene Fenster.

Swing enthält eine Container-Klasse "Box", die "BoxLayout" verwendet. Mit statischen Methoden dieser Klasse lässt sich die Anordnung der Komponenten beeinflussen. ... Layout7() { Box bv = Box.createVerticalBox(); for(int i = 0; i < 4; i++) { bv.add(new JButton("BV " + i)); bv.add(Box.createVerticalStrut(4)); } Box bh = Box.createHorizontalBox(); bh.add(new JButton("--- BH 0 ---")); for(int i = 1; i < 4; i++) {

Bild 8.8 BoxLayout

Page 131: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 131

bh.add(Box.createHorizontalStrut(6)); bh.add(new JButton("BH " + i)); } Container cp = getContentPane(); cp.add(BorderLayout.EAST, bv); cp.add(BorderLayout.SOUTH, bh); ...

Bild 8.9 zeigt das nach dieser Änderung ausgege-bene Fenster.

Die statischen Methoden "create...Strut" (Strebe, Stütze) erzeugen unsichtbare Komponenten mit vorgebbaren Abmessungen, mit denen sich der Abstand zwischen den Komponenten beeinflussen lässt. Eine vollständigere Beschreibung der Methoden aus "Box" ist z.B. in [2] zu finden.

8.4 JDialog und JOptionPane Mit "JDialog" und "JOptionPane" lassen sich Fenster ausgeben, die von einem anderen Fenster abhängig sind.

JDialog

Im folgenden Programm wird ein modales Dialogfenster eingesetzt. Man nennt ein Dialog-fenster "modal", wenn es alle anderen Eingaben einer Anwendung blockiert, solange es nicht geschlossen worden ist. Beispiel, Dialog1 import java.awt.*; import java.awt.event.*; import javax.swing.*; class MyDialog extends JDialog implements ActionListener { MyDialog(JFrame parent) { //JDialog(Dialog owner, String title, boolean modal) super(parent, "My dialog", true); Container cnt = getContentPane(); cnt.setLayout(new FlowLayout()); cnt.add(new JLabel("Please press OK")); JButton btn = new JButton("OK"); btn.addActionListener(this); cnt.add(btn); setDefaultCloseOperation(DISPOSE_ON_CLOSE); Rectangle rct = new Rectangle(parent.getBounds()); setBounds(rct.x+40, rct.y+30, 160, 110); }

Bild 8.9 BoxLayout mit Abständen

Page 132: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 132

public void actionPerformed(ActionEvent e) { // Disposes the Dialog and then causes setVisible(true) in // the calling program to return dispose(); } } public class Dialog1 extends JFrame implements ActionListener { Dialog1() { getContentPane().setLayout(new BorderLayout()); JButton btn = new JButton("Show Dialog"); getContentPane().add(BorderLayout.SOUTH, btn); btn.addActionListener(this); } public void actionPerformed(ActionEvent e) { MyDialog dlg = new MyDialog(this); // Makes the Dialog visible dlg.setVisible(true); } public static void main(String[] args) { JFrame window = new Dialog1(); window.setTitle("Dialog 1"); window.setSize(300, 200); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.10 zeigt die vom Programm ausgegebenen Fenster.

MyDialog dlg = new MyDialog(this); dlg.setVisible(true);

Der Aufruf von "setVisible(true)" aktiviert das Dialogfenster und führt dazu, dass es auf dem Bildschirm sichtbar wird.

dispose();

Das Dialogfenster wird "beseitigt". Bei modalen Dialogfenstern kehrt "setVisible(true)" erst dann in das aufrufende Programm zurück.

Aufgabe 8.2

Schreiben Sie ein Programm "TicTacToe", das die in Bild 8.11 gegebenen Fenster ausgibt. Das Programm soll es zwei Personen ermöglichen, "TicTacToe" zu spielen.

Bild 8.10 Modales Dialogfenster

Bild 8.11 TicTacToe

Page 133: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 133

JOptionPane Mit "JOptionPane" kann man mit geringem Aufwand kurze standardisierte Meldungen oder Eingaben programmieren. Dabei lassen sich folgende Aufgabenbereiche abdecken: − Mitteilung mit der Schaltfläche "Ok". − Eingabe mit den Schaltflächen "Ok" und "Cancel". − Bestätigung (Mitteilung oder Frage) mit unterschiedlichen Schaltflächen. − Auswahl für beliebige Daten mit Schaltflächen. Hier wird nur auf die ersten beiden Aufgabenbereiche eingegangen. Vollständigere Erläute-rungen sind z.B. in [1] zu finden.

Mitteilung (message) Mit der statischen Methode "showMessageDialog" kann man eine Mitteilung ausgeben. Das Mitteilungsfenster ist modal. Solange es nicht beendet wird, blockiert es also alle anderen Eingaben einer Anwendung. Das Fenster enthält eine Schaltfläche "Ok". public static void showMessageDialog(Component parent, Object message, String title, int messageType)

parent: "Elternfenster", in dem das Mitteilungsfenster zentriert ausgegeben wird. message: Häufig ein String, der im Fenster als Mitteilung ausgegeben wird. Andere

Objekte sind ebenfalls möglich, wie z.B. ein Icon. title: Der String wird in der Kopfleiste ausgegeben. messageType: Typ der Mitteilung, zulässig sind PLAIN_MESSAGE,

ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE oder QUESTION_MESSAGE.

Beispiel, ShowMessageBox import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ShowMessageBox extends JFrame implements ActionListener { ShowMessageBox() { JButton btn = new JButton("Show error window"); btn.addActionListener(this); getContentPane().add(BorderLayout.SOUTH, btn); } public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(this, "')' expected in line 12, column 34", "Fatal error", JOptionPane.ERROR_MESSAGE); } public static void main(String[] args) { ShowMessageBox window = new ShowMessageBox();

Page 134: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 134

window.setTitle("MessageBox Demo"); window.setSize(360, 200); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.12 zeigt das vom Programm aus-gegebene Mitteilungsfenster. Mit der Aus-nahme der "PLAIN_MESSAGE" enthalten alle Fenster Icons, die auf die Art der jeweiligen Meldung hinweisen. Eingabe (input)

Die statische Methode "showInputDialog" gibt ein Fenster mit Eingabefeld und den Schalt-flächen "Ok" und "Cancel" aus. Das Fenster ist modal. public static String showInputDialog(Component parent, Object message, String title, int messageType)

Die Bedeutung der vier Parameter unterscheidet sich nicht von "showMessageDialog".

Rückgabewert: Eingegebener Text oder "null", wenn die Eingabe abgebrochen worden ist. Beispiel, ShowInputBox import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ShowInputBox extends JFrame implements ActionListener { ShowInputBox() { JButton btn = new JButton("Show input box"); btn.addActionListener(this); getContentPane().add(BorderLayout.SOUTH, btn); } public void actionPerformed(ActionEvent e) { String inp = JOptionPane.showInputDialog(this, "Please enter your name", "Input box", JOptionPane.QUESTION_MESSAGE); String mss = (inp != null)? "Your name is " + inp: "Name not entered"; JOptionPane.showMessageDialog(this, mss, "Message box", JOptionPane.INFORMATION_MESSAGE); } public static void main(String[] args) { ShowInputBox window = new ShowInputBox(); window.setTitle("InputBox Demo"); window.setSize(360, 200);

Bild 8.12 Mitteilungsfenster

Page 135: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 135

window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.13 zeigt das vom Programm ausge-gebene Eingabefenster.

8.5 JCheckBox und JRadioButton Die Klassen "JRadioButton" und "JCheckBox" stellen "Schalter" zur Verfügung, die vom Anwender ein- und ausgeschaltet werden können. Instanzen von "JRadioButton" werden in aller Regel zu Gruppen zusammengefasst, in denen immer genau einer der Schalter aktiviert sein kann. Beispiel, RButtonCBox import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class RButtonCBox extends JFrame implements ActionListener{ final private String TXT[] = {"zero", "one", "two"}; private JRadioButton rb[] = new JRadioButton[TXT.length]; private JCheckBox cb[] = new JCheckBox[TXT.length]; RButtonCBox() { Box brb = Box.createVerticalBox(); brb.setBorder(new LineBorder(Color.GRAY)); ButtonGroup group = new ButtonGroup(); for(int i = 0; i < TXT.length; i++) { rb[i] = new JRadioButton("Button " + TXT[i], false); rb[i].addActionListener(this); brb.add(rb[i]); group.add(rb[i]); } rb[0].setSelected(true); Box bcb = Box.createVerticalBox(); bcb.setBorder(new LineBorder(Color.GRAY)); for(int i = 0; i < TXT.length; i++) { cb[i] = new JCheckBox("Box " + TXT[i], false); cb[i].addActionListener(this); bcb.add(cb[i]); } Container con = getContentPane(); con.setLayout(new GridLayout(1, 2, 2, 2)); con.add(brb);

Bild 8.13 Eingabefenster

Page 136: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 136

con.add(bcb); } public void actionPerformed(ActionEvent e) { String srb = "", scb = ""; for(int i = 0; i < TXT.length; i++) { if(rb[i].isSelected()) srb += i; if(cb[i].isSelected()) scb += i + " "; } System.out.println("RadioButton: " + srb + " CheckBox: " + scb); } public static void main(String[] args) { JFrame window = new RButtonCBox(); window.setTitle("RButton CBox"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.14 zeigt das Programmfenster. Auf der Konsole wird der jeweils aktuelle Zustand der sechs Schalter ausgegeben. Aufgabe 8.3

Schreiben Sie ein Programm, das das in Bild 8.15 gegebene Fenster ausgibt. Wenn der Benutzer die Schaltfläche "Ok" betätigt, soll der aktuelle Zustand der elf Schalter auf der Konsole ausge-geben werden.

8.6 JTextField, JTextArea und JScrollPane

"JTextField" stellt ein einzeiliges und "JTextArea" ein mehrzeiliges Feld zur Anzeige und Eingabe von Texten zur Verfügung. "JScrollPane" erzeugt bei Bedarf horizontale und vertikale "Schieber".

JTextField

Das folgende Programm zeigt die Vorgehensweise bei der Eingabe mit "JTextField". Wenn der Benutzer den Textcursor (Caret) im Eingabefeld bewegt, wird die Methode "CaretUpdate"

Bild 8.14 JRadioButton und JCheckBox

Bild 8.15 JRadioButton und JCheckBox

Page 137: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 137

aus "CaretListener" aufgerufen. Die Return-Taste führt zur Ausführung von "Action-Performed" aus "ActionListener". Beispiel, TextFieldDemo import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; // For "CaretEvent" public class TextFieldDemo extends JFrame implements ActionListener, CaretListener { // JTextField(int columns) or // JTextField(String text) or // JTextField(String text, int columns) private JTextField tf = new JTextField(16); TextFieldDemo() { Box bh = Box.createHorizontalBox(); bh.add(new JLabel(" Name: ", JLabel.LEFT)); tf.addActionListener(this); tf.addCaretListener(this); bh.add(tf); Container con = getContentPane(); con.setLayout(new GridLayout(2, 1, 4, 4)); con.add(new JLabel(" Type and press Return ")); con.add(bh); } public void actionPerformed(ActionEvent e) { System.out.println("Command: " + e.getActionCommand()); System.out.println("Text: " + tf.getText()); } public void caretUpdate(CaretEvent e) { System.out.println("Pos: " + e.getDot() + " " + tf.getText()); } public static void main(String[] args) { JFrame window = new TextFieldDemo(); window.setTitle("Text Field Demo"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.16 zeigt das einzeilige Eingabefeld und die zugehö-rige Konsolenausgabe.

Bild 8.16 JTextField und Konsolenausgabe

Auf der Konsole Pos: 1 T Pos: 2 Te Pos: 3 Tes Pos: 4 Test Command: Test Text: Test

Page 138: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 138

Aufgabe 8.4

Schreiben Sie ein Programm, das das in Bild 8.17 gegebene Fenster ausgibt. Wenn der Benutzer die Schaltfläche "Ok" betätigt, sollen die einge-tragenen Daten zur Kontrolle auf der Konsole ausgegeben werden.

Aufgabe 8.5

Schreiben Sie ein Programm, das den einfachen Rechner aus Bild 8.18 ausgibt. Wenn man eine Taste betätigt, soll das Programm hier nur die zugehörige Beschriftung im Rechner-display ausgeben.

(Der Rechner wird in einer Übungsaufgabe zu diesem Abschnitt vervollständigt.)

JTextArea und JScrollPane

"JTextArea" stellt ein mehrzeiliges Feld zur Anzeige und Eingabe von Texten zur Verfügung. Die Klasse ist aber nicht in der Lage, den Text zu scrollen, wenn er nicht vollständig in das Ausgabefeld passt. Für diesen Zweck ist "JScrollPane" vorgesehen.

Im folgenden Beispiel wird ein einfacher Editor programmiert. Das Programm zeigt die Vor-gehensweise beim Einsatz von "JTextArea" und "JScrollPane". Beispiel, BasicEditor import java.awt.*; import java.awt.event.*; import javax.swing.*; public class BasicEditor extends JFrame implements ActionListener { final static String S[] = {"Duplicate Text", "Clear Text"}; private JButton b[] = {new JButton(S[0]), new JButton(S[1])}; // JTextArea(String text, int rows, int columns) private JTextArea ta = new JTextArea( "Das ist ein Test des einfachen Editors. ", 8, 26); BasicEditor () { ta.setFont(new Font("Arial", Font.ITALIC, 12)); // Long lines will be wrapped, default: false I ta.setLineWrap(true) ; // Lines will be wrapped at word boundaries, default: false

Bild 8.17 Name und Adresse

Bild 8.18 Einfacher Rechner

Page 139: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 139

ta.setWrapStyleWord(true); JPanel panel = new JPanel(new GridLayout(1, 2)); for(int i = 0; i < b.length; i++) { panel.add(b[i]); b[i].addActionListener(this); } getContentPane().add(BorderLayout.CENTER, new JScrollPane(ta)); getContentPane().add(BorderLayout.SOUTH, panel); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd.equals(S[1])) ta.setText(""); else { String txt = ta.getText(); if(txt.length() < 16384) ta.setText(txt + txt); else JOptionPane.showMessageDialog(this, "Text too long, not duplicated", "Simple Editor", JOptionPane.ERROR_MESSAGE); } } public static void main(String[] args) { JFrame window = new BasicEditor(); window.setTitle("Basic Editor"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

In Bild 8.19 ist das Programmfenster zu finden. Da der Text am Zeilenende automatisch um-gebrochen wird, ist hier nur ein vertikaler Schieber erforderlich.

8.7 JSlider und JProgressbar

Mit der Klasse "JSlider" lässt sich ein Schieberegler ausgeben, der mit Markierungen und einer Bemaßung versehen werden kann. Wenn der Benutzer den Regler betätigt, wird die Methode "stateChanged" des Interface "ChangeListener" ausgeführt (Tabelle 8.1). Tabelle 8.1 ChangeListener und zugehörige Methode Listener-Interface Methode Auslösende Aktion ChangeListener stateChanged Der Zustand hat sich geändert, der Anwender hat den

Schieberegler betätigt

Bild 8.19 Einfacher Editor

Page 140: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 140

Die Klasse "JProgressBar" kann man zur Darstellung anloger Werte einsetzen. Eine typische Anwendung ist zum Beispiel eine Fortschrittsanzeige bei länger dauernden Vorgängen. Beispiel, CelsiusConverter import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; // For ChangeListener public class CelsiusConverter extends JFrame implements ChangeListener { // JSlider(int orientation, int min, int max, int initialValue) JSlider sl = new JSlider(JSlider.HORIZONTAL, -20, 100, 0); // JProgressBar(int orient, int min, int max) JProgressBar pb = new JProgressBar( JProgressBar.HORIZONTAL, -4, 212); JLabel cfLabel = new JLabel("0 °C = 32 °F", JLabel.CENTER); CelsiusConverter () { JLabel slLabel = new JLabel("Temperatur in °C", JLabel.CENTER); slLabel.setAlignmentX(Component.CENTER_ALIGNMENT); JLabel pbLabel = new JLabel("Temperatur in °F", JLabel.CENTER); pbLabel.setAlignmentX(Component.CENTER_ALIGNMENT); cfLabel.setAlignmentX(Component.CENTER_ALIGNMENT); sl.setMajorTickSpacing(40); sl.setMinorTickSpacing(10); sl.setPaintTicks(true); sl.setPaintLabels(true); sl.addChangeListener(this); // public static Border createEmptyBorder(int spaceTop, // int spaceLeft, int spaceBottom, int spaceRight) sl.setBorder(BorderFactory.createEmptyBorder(2, 2, 10, 6)); pb.setValue(32); pb.setBorder(BorderFactory.createEmptyBorder(2, 2, 10, 6)); pb.setStringPainted(true); Container con = getContentPane(); con.setLayout(new BoxLayout(con, BoxLayout.Y_AXIS)); con.add(slLabel); con.add(sl); con.add(pbLabel); con.add(pb); con.add(cfLabel); } public void stateChanged(ChangeEvent e) { int tempF = (int) (1.8*sl.getValue() + 32); pb.setValue(tempF); cfLabel.setText(sl.getValue() + " °C = " + tempF +" °F"); } public static void main(String[] args) {

Page 141: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 141

JFrame window = new CelsiusConverter(); window.setTitle("Celsius Converter"); window.pack(); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.20 zeigt das Programmfenster. Die Temperatur in Grad Celsius wird am Schieberegler mit der Maus oder mit der Tastatur eingestellt.

8.8 JMenu und JPopupmenu

Ein Menü ("JMenu") ist Bestandteil einer Menüleiste ("JMenuBar"). Wenn man einen Menü-eintrag ("JMenuItem") anklickt, wird die Methode "ActionPerformed" des Interface "Action-Listener" ausgeführt. Das folgende Programm zeigt, wie man eine einfache Menüstruktur implementiert. Beispiel, Menu1 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Menu1 extends JFrame implements ActionListener { Menu1() { JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu menu1 = new JMenu("File"); menuBar.add(menu1); addMenuItem(menu1, new JMenuItem("Load")); addMenuItem(menu1, new JMenuItem("Save")); menu1.addSeparator(); addMenuItem(menu1, new JMenuItem("Exit")); JMenu menu2 = new JMenu("Options"); menuBar.add(menu2); addMenuItem(menu2, new JMenuItem("Settings")); } private void addMenuItem(JMenu m, JMenuItem mi) { m.add(mi); mi.addActionListener(this); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd.equals("Exit")) System.exit(0); JOptionPane.showMessageDialog(this, cmd, "Menu 1", JOptionPane.INFORMATION_MESSAGE); }

Bild 8.20 Celsius Converter

Page 142: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 142

public static void main(String[] args) { JFrame window = new Menu1(); window.setTitle("Menu 1"); window.setSize(300, 180); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8.21 zeigt das vom Programm ausgegebene Fenster. Der Menüeintrag "Exit" hat die zu erwartende Wirkung: das Programm wird beendet. Die anderen Menüeintragungen führen hier nur dazu, dass der jeweilige Menütext in einem Meldungsfenster zur Bestätigung ausgegeben wird. Mit der Methode "setActionCommand" kann man einem Menüeintrag einen Text zuweisen, der von der Beschriftung dieses Menüeintrags abweicht. Auf diese Weise lassen sich Menü-eintragungen mit demselben Text unterscheiden. Im folgenden Programmausschnitt ist die Vorgehensweise zu finden. ... // wie im vorausgehenden Beispiel Menu1() { JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu menu1 = new JMenu("File"); menuBar.add(menu1); addMenuItem(menu1, new JMenuItem("Exit"), "StopProg"); JMenu menu2 = new JMenu("Rectangle"); menuBar.add(menu2); addMenuItem(menu2, new JMenuItem("Red"), "RectRed"); JMenu menu3 = new JMenu("Circle"); menuBar.add(menu3); addMenuItem(menu3, new JMenuItem("Red"), "CircleRed"); } private void addMenuItem(JMenu m, JMenuItem mi, String s) { m.add(mi); mi.addActionListener(this); mi.setActionCommand(s); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd.equals("StopProg")) System.exit(0); JOptionPane.showMessageDialog(this, cmd, "Menu 1", JOptionPane.INFORMATION_MESSAGE);

Bild 8.21 Menü

Page 143: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 143

} ...

Bild 8.22 zeigt das vom Programm ausgegebene Fenster.

Eine vollständigere Beschreibung der Möglich-keiten ist z.B. in [1] zu finden.

Kontextmenü Kontextmenüs (Popup-Menüs) werden mit einem rechten Mausklick auf die jeweilige Komponente angefordert und enthalten auf diese Komponente bezogene Menüepunkte. Beispiel, Menu2 import java.awt.*; import java.awt.event.*; import javax.swing.*; class MyPanel extends JPanel { private Color cl; MyPanel(Color c) {cl = c; } void setColor(Color c) { cl = c; } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(cl); g.drawRect(getSize().width/2-50, getSize().height/2-50, 100, 100); } } public class Menu2 extends JFrame implements ActionListener { private final String[] TXT={"Black","White","Red" }; private final Color[] COL={Color.BLACK,Color.WHITE, Color.RED}; final private MyPanel mypnl = new MyPanel(COL[0]); final private JPopupMenu popup = new JPopupMenu(); Menu2() { addMenuItem(popup, new JMenuItem(TXT[0])); addMenuItem(popup, new JMenuItem(TXT[1])); popup.addSeparator(); addMenuItem(popup, new JMenuItem(TXT[2])); addMouseListener(new MyMouseListener()); getContentPane().add(mypnl); } private void addMenuItem(JPopupMenu pm, JMenuItem mi) { pm.add(mi); mi.addActionListener(this); }

Bild 8.22 "Red" in "Rectangle" und in "Circle"

Page 144: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 144

public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); for(int i = 0; i < TXT.length; i++) if(cmd.equals(TXT[i])) mypnl.setColor(COL[i]); repaint(); } class MyMouseListener extends MouseAdapter { public void mouseReleased(MouseEvent e) { if(e.isPopupTrigger()) popup.show(e.getComponent(), e.getX(), e.getY()); } } public static void main(String[] args) { Menu2 window = new Menu2(); window.setTitle("Popup"); window.setSize(260, 180); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Bild 8,.23 zeigt das vom Programm ausgegebene Fenster. Mit Hilfe des Kontextmenüs lässt sich die Farbe der Rechteckumrandung ändern.

8.9 JFileChooser Die Klasse "JFileChooser" stellt die üblichen Dialogfenster zur Verfügung, die man zum Laden oder Speichern einer Datei benötigt.

Mit dem folgenden Programm lassen sich Dateien zum Laden oder Speichern auswählen. Die Dateien werden dann aber nicht wirklich geladen oder gespeichert, die jeweilige Auswahl wird vielmehr nur in einem Textfeld protokolliert. Beispiel, FileChooserDemo import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; public class FileChooserDemo extends JFrame implements ActionListener { final String[] TXT = {"Open", "Save"}; final JTextArea log = new JTextArea(10, 40); final JFileChooser fc = new JFileChooser(); public FileChooserDemo() { log.setEditable(false); log.setMargin(new Insets(5, 5, 5, 5));

Bild 8.23 Kontextmenü

Page 145: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 145

JPanel pnl = new JPanel(); for(int i = 0; i < TXT.length; i++) { JButton btn = new JButton(TXT[i]); btn.addActionListener(this); pnl.add(btn); } Container contentPane = getContentPane(); contentPane.add(new JScrollPane(log), BorderLayout.CENTER); contentPane.add(pnl, BorderLayout.SOUTH); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); String mss = cmd + ": Cancelled"; int ret = (cmd.equals(TXT[0]))? fc.showOpenDialog(this): fc.showSaveDialog(this); if(ret == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); mss = cmd + ": " + file.getPath(); } log.append(mss + '\n'); } public static void main(String[] args) { JFrame window = new FileChooserDemo(); window.setTitle("File Chooser Demo"); window.pack(); window.setResizable(false); window.setDefaultCloseOperation(EXIT_ON_CLOSE); window.setVisible(true); } }

Vom Programm ausge-gebene Fenster sind in Bild 8.24 zu finden. Es ist gerade der Dialog zum Öffnen einer Datei zu sehen.

Bild 8.24 File Chooser

Page 146: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

8 Swing-Komponenten 146

8.10 Übungsaufgaben Übungsaufgabe 8.1

In einer der Aufgaben zu diesem Abschnitts ist das Programm eines einfachen Rechners entwickelt worden (Bild 8.25). Wenn man eine Taste betätigt, gibt das Programm bisher aber nur die zugehörige Beschriftung im Rechnerdisplay aus. Erweitern Sie das Programm nun zu einem funktionsfähigen einfachen Rechner. Übungsaufgabe 8.2

Schreiben Sie einen einfachen Editor (Bild 8.26) für Textdateien. Es soll möglich sein, eine Datei über "File | Open" zu öffnen, den Text zu editieren und den geänderten Text dann mit "File | Save As" in der ursprünglichen oder in einer anderen Datei zu speichern. Verwenden Sie zum Öffnen und zum Speichern der Textdatei jeweils eine Instanz von "JFileChooser".

Bild 8.25 Einfacher Rechner

Bild 8.26 MyEditor

Page 147: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang

9.1 Schlüsselwörter (keywords) in Java Liste der Schlüsselwörter (reserviert) abstract double int strictfp ** boolean else interface super break extends long switch byte final native synchronized case finally new this catch float package throw char for private throws class goto * protected transient const * if public try continue implements return void default import short volatile do instanceof static while

* Gegenwärtig nicht benutzt. ** In Java 2 dazugekommen. true, false und null sind keine Schlüsselwörter, sie sind aber dennoch reserviert.

9.2 Einige Java-Begriffe

J2SE: Java 2 Standard Edition

J2EE: Java 2 Enterprise Edition für die Programmierung auf Server-Seite

J2ME: Java 2 Micro Edition für eingebettete Systeme (embedded systems)

Abstract Windows Toolkit (AWT, ab JDK 1.0): Stellt elementare Grafik- und Fenster-funktionen zur Verfügung.

Swing Toolset (in der aktuellen Form ab JDK 1.2): Konzept und Schnittstellen für platt-formübergreifende GUI Applikationen (Graphical User Interface). Swing Applikationen können das typische Aussehen (Look & Feel) einer Plattform annehmen (Windows, Macintosh, Solaris). Die Swing Komponenten enthalten Duplikate aller AWT-Komponenten und darüber hinaus zahlreiche zusätzliche Komponenten.

Beans, Javabeans (ab JDK 1.1): Wiederverwendbare Softwarebausteine. Beans ermöglichen das "Zusammenstellen" von Programmen aus vorgefertigten Komponenten in einer grafischen Entwicklungsumgebung (IDE, Integrated Development Environment).

Java Database Connectivity (JDBC): Schnittstelle zum Zugriff auf Datenbanken über SQL-Befehle (System Querry Language). Die Schnittstelle muss dazu von der Datenbank unter-stützt werden.

Remote Method Invocation (RMI): Programme können mit RMI in verteilten Systemen auf Objekte von anderen Anwendungen zugreifen, die im Netzwerk von anderen Java-VM ausgeführt werden.

Page 148: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 148

9.3 Package java.lang

9.3.1 Class Summary

Boolean The Boolean class wraps a value of the primitive type boolean in an object. Byte The Byte class is the standard wrapper for byte values. Character The Character class wraps a value of the primitive type char in an object. Character.Subset Instances of this class represent particular subsets of the Unicode character set.

Character.UnicodeBlock A family of character subsets representing the character blocks defined by the Unicode 2.0 specification.

Class Instances of the class Class represent classes and interfaces in a running Java application.

ClassLoader The class ClassLoader is an abstract class.

Compiler The Compiler class is provided to support Java-to-native-code compilers and related services.

Double The Double class wraps a value of the primitive type double in an object. Float The Float class wraps a value of primitive type float in an object.

InheritableThreadLocal This class extends ThreadLocal to provide inheritance of values from parent Thread to child Thread: when a child thread is created, the child receives initial values for all InheritableThreadLocals for which the parent has values.

Integer The Integer class wraps a value of the primitive type int in an object. Long The Long class wraps a value of the primitive type long in an object.

Math The class Math contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.

Number The abstract class Number is the superclass of classes Byte, Double, Float, Integer, Long, and Short.

Object Class Object is the root of the class hierarchy.

Package Package objects contain version information about the implementation and specification of a Java package.

Process The Runtime.exec methods create a native process and return an instance of a subclass of Process that can be used to control the process and obtain information about it.

Runtime Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running.

RuntimePermission This class is for runtime permissions.

SecurityManager The security manager is a class that allows applications to implement a security policy.

Short The Short class is the standard wrapper for short values.

StrictMath The class StrictMath contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.

String The String class represents character strings. StringBuffer A string buffer implements a mutable sequence of characters. System The System class contains several useful class fields and methods. Thread A thread is a thread of execution in a program. ThreadGroup A thread group represents a set of threads. ThreadLocal This class provides ThreadLocal variables.

Page 149: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 149

Throwable The Throwable class is the superclass of all errors and exceptions in the Java language.

Void The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the primitive Java type void.

9.3.2 Class java.lang.Math

Field Summary static double E The double value that is closer than any other to e, the base of the natural

logarithms. static double PI The double value that is closer than any other to pi, the ratio of the circumference

of a circle to its diameter.

Method Summary static double abs(double a)

Returns the absolute value of a double value. static float abs(float a)

Returns the absolute value of a float value. static int abs(int a)

Returns the absolute value of an int value. static long abs(long a)

Returns the absolute value of a long value. static double acos(double a)

Returns the arc cosine of an angle, in the range of 0.0 through pi. static double asin(double a)

Returns the arc sine of an angle, in the range of -pi/2 through pi/2. static double atan(double a)

Returns the arc tangent of an angle, in the range of -pi/2 through pi/2. static double atan2(double a, double b)

Converts rectangular coordinates (b, a) to polar (r, theta). static double ceil(double a)

Returns the smallest (closest to negative infinity) double value that is not less than the argument and is equal to a mathematical integer.

static double cos(double a) Returns the trigonometric cosine of an angle.

static double exp(double a) Returns the exponential number e (i.e., 2.718...) raised to the power of a double value.

static double floor(double a) Returns the largest (closest to positive infinity) double value that is not greater than the argument and is equal to a mathematical integer.

static double IEEEremainder(double f1, double f2) Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard.

static double log(double a) Returns the natural logarithm (base e) of a double value.

static double max(double a, double b) Returns the greater of two double values.

static float max(float a, float b) Returns the greater of two float values.

Page 150: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 150

static int max(int a, int b) Returns the greater of two int values.

static long max(long a, long b) Returns the greater of two long values.

static double min(double a, double b) Returns the smaller of two double values.

static float min(float a, float b) Returns the smaller of two float values.

static int min(int a, int b) Returns the smaller of two int values.

static long min(long a, long b) Returns the smaller of two long values.

static double pow(double a, double b) Returns of value of the first argument raised to the power of the second argument.

static double random() Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.

static double rint(double a) Returns the double value that is closest in value to a and is equal to a mathematical integer.

static long round(double a) Returns the closest long to the argument.

static int round(float a) Returns the closest int to the argument.

static double sin(double a) Returns the trigonometric sine of an angle.

static double sqrt(double a) Returns the correctly rounded positive square root of a double value.

static double tan(double a) Returns the trigonometric tangent of an angle.

static double toDegrees(double angrad) Converts an angle measured in radians to the equivalent angle measured in degrees.

static double toRadians(double angdeg) Converts an angle measured in degrees to the equivalent angle measured in radians.

9.3.3 Class java.lang.String

Method Summary char charAt(int index)

Returns the character at the specified index. int compareTo(Object o)

Compares this String to another Object. int compareTo(String anotherString)

Compares two strings lexicographically. int compareToIgnoreCase(String str)

Compares two strings lexicographically, ignoring case considerations. String concat(String str)

Concatenates the specified string to the end of this string. static String copyValueOf(char[] data)

Returns a String that is equivalent to the specified character array.

Page 151: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 151

static String copyValueOf(char[] data, int offset, int count) Returns a String that is equivalent to the specified character array.

boolean endsWith(String suffix) Tests if this string ends with the specified suffix.

boolean equals(Object anObject) Compares this string to the specified object.

boolean equalsIgnoreCase(String anotherString) Compares this String to another String, ignoring case considerations.

byte[] getBytes() Convert this String into bytes according to the platform's default character encoding, storing the result into a new byte array.

void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) Deprecated. This method does not properly convert characters into bytes. As of JDK 1.1, the preferred way to do this is via the getBytes(String enc) method, which takes a character-encoding name, or the getBytes() method, which uses the platform's default encoding.

byte[] getBytes(String enc) Convert this String into bytes according to the specified character encoding, storing the result into a new byte array.

void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) Copies characters from this string into the destination character array.

int hashCode() Returns a hashcode for this string.

int indexOf(int ch) Returns the index within this string of the first occurrence of the specified character.

int indexOf(int ch, int fromIndex) Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

int indexOf(String str) Returns the index within this string of the first occurrence of the specified substring.

int indexOf(String str, int fromIndex) Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

String intern() Returns a canonical representation for the string object.

int lastIndexOf(int ch) Returns the index within this string of the last occurrence of the specified character.

int lastIndexOf(int ch, int fromIndex) Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index.

int lastIndexOf(String str) Returns the index within this string of the rightmost occurrence of the specified substring.

int lastIndexOf(String str, int fromIndex) Returns the index within this string of the last occurrence of the specified substring.

int length() Returns the length of this string.

boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) Tests if two string regions are equal.

boolean regionMatches(int toffset, String other, int ooffset, int len) Tests if two string regions are equal.

Page 152: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 152

String replace(char oldChar, char newChar) Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.

boolean startsWith(String prefix) Tests if this string starts with the specified prefix.

boolean startsWith(String prefix, int toffset) Tests if this string starts with the specified prefix beginning a specified index.

String substring(int beginIndex) Returns a new string that is a substring of this string.

String substring(int beginIndex, int endIndex) Returns a new string that is a substring of this string.

char[] toCharArray() Converts this string to a new character array.

String toLowerCase() Converts all of the characters in this String to lower case using the rules of the default locale, which is returned by Locale.getDefault.

String toLowerCase(Locale locale) Converts all of the characters in this String to lower case using the rules of the given Locale.

String toString() This object (which is already a string!) is itself returned.

String toUpperCase() Converts all of the characters in this String to upper case using the rules of the default locale, which is returned by Locale.getDefault.

String toUpperCase(Locale locale) Converts all of the characters in this String to upper case using the rules of the given locale.

String trim() Removes white space from both ends of this string.

static String valueOf(boolean b) Returns the string representation of the boolean argument.

static String valueOf(char c) Returns the string representation of the char argument.

static String valueOf(char[] data) Returns the string representation of the char array argument.

static String valueOf(char[] data, int offset, int count) Returns the string representation of a specific subarray of the char array argument.

static String valueOf(double d) Returns the string representation of the double argument.

static String valueOf(float f) Returns the string representation of the float argument.

static String valueOf(int i) Returns the string representation of the int argument.

static String valueOf(long l) Returns the string representation of the long argument.

static String valueOf(Object obj) Returns the string representation of the Object argument.

Page 153: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 153

9.4 Class java.awt.Graphics

Method Summary abstract

void clearRect(int x, int y, int width, int height) Clears the specified rectangle by filling it with the background color of the current drawing surface.

abstract void

clipRect(int x, int y, int width, int height) Intersects the current clip with the specified rectangle.

abstract void

copyArea(int x, int y, int width, int height, int dx, int dy) Copies an area of the component by a distance specified by dx and dy.

abstract Graphics

create() Creates a new Graphics object that is a copy of this Graphics object.

Graphics create(int x, int y, int width, int height) Creates a new Graphics object based on this Graphics object, but with a new translation and clip area.

abstract void

dispose() Disposes of this graphics context and releases any system resources that it is using.

void draw3DRect(int x, int y, int width, int height, boolean raised) Draws a 3-D highlighted outline of the specified rectangle.

abstract void

drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) Draws the outline of a circular or elliptical arc covering the specified rectangle.

void drawBytes(byte[] data, int offset, int length, int x, int y) Draws the text given by the specified byte array, using this graphics context's current font and color.

void drawChars(char[] data, int offset, int length, int x, int y) Draws the text given by the specified character array, using this graphics context's current font and color.

abstract boolean

drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) Draws as much of the specified image as is currently available.

abstract boolean

drawImage(Image img, int x, int y, ImageObserver observer) Draws as much of the specified image as is currently available.

abstract boolean

drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) Draws as much of the specified image as has already been scaled to fit inside the specified rectangle.

abstract boolean

drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) Draws as much of the specified image as has already been scaled to fit inside the specified rectangle.

abstract boolean

drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) Draws as much of the specified area of the specified image as is currently available, scaling it on the fly to fit inside the specified area of the destination drawable surface.

abstract boolean

drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) Draws as much of the specified area of the specified image as is currently available, scaling it on the fly to fit inside the specified area of the destination drawable surface.

abstract void

drawLine(int x1, int y1, int x2, int y2) Draws a line, using the current color, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.

Page 154: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 154

abstract void

drawOval(int x, int y, int width, int height) Draws the outline of an oval.

abstract void

drawPolygon(int[] xPoints, int[] yPoints, int nPoints) Draws a closed polygon defined by arrays of x and y coordinates.

void drawPolygon(Polygon p) Draws the outline of a polygon defined by the specified Polygon object.

abstract void

drawPolyline(int[] xPoints, int[] yPoints, int nPoints) Draws a sequence of connected lines defined by arrays of x and y coordinates.

void drawRect(int x, int y, int width, int height) Draws the outline of the specified rectangle.

abstract void

drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Draws an outlined round-cornered rectangle using this graphics context's current color.

abstract void

drawString(AttributedCharacterIterator iterator, int x, int y) Draws the text given by the specified iterator, using this graphics context's current color.

abstract void

drawString(String str, int x, int y) Draws the text given by the specified string, using this graphics context's current font and color.

void fill3DRect(int x, int y, int width, int height, boolean raised) Paints a 3-D highlighted rectangle filled with the current color.

abstract void

fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) Fills a circular or elliptical arc covering the specified rectangle.

abstract void

fillOval(int x, int y, int width, int height) Fills an oval bounded by the specified rectangle with the current color.

abstract void

fillPolygon(int[] xPoints, int[] yPoints, int nPoints) Fills a closed polygon defined by arrays of x and y coordinates.

void fillPolygon(Polygon p) Fills the polygon defined by the specified Polygon object with the graphics context's current color.

abstract void

fillRect(int x, int y, int width, int height) Fills the specified rectangle.

abstract void

fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Fills the specified rounded corner rectangle with the current color.

void finalize() Disposes of this graphics context once it is no longer referenced.

abstract Shape

getClip() Gets the current clipping area.

abstract Rectangle

getClipBounds() Returns the bounding rectangle of the current clipping area.

Rectangle getClipBounds(Rectangle r) Returns the bounding rectangle of the current clipping area.

Rectangle getClipRect() Deprecated. As of JDK version 1.1, replaced by getClipBounds().

abstract Color

getColor() Gets this graphics context's current color.

abstract Font

getFont() Gets the current font.

FontMetrics getFontMetrics() Gets the font metrics of the current font.

Page 155: bkovertretung.bplaced.netbkovertretung.bplaced.net/wordpress/wp-content/uploads/2018/01/Java-Skript-V7.pdf · Inhalt 1 OOP I : Klassen und Objekte ______________________________________________5

9 Anhang 155

abstract FontMetrics

getFontMetrics(Font f) Gets the font metrics for the specified font.

boolean hitClip(int x, int y, int width, int height) Returns true if the specified rectangular area intersects the bounding rectangle of the current clipping area.

abstract void

setClip(int x, int y, int width, int height) Sets the current clip to the rectangle specified by the given coordinates.

abstract void

setClip(Shape clip) Sets the current clipping area to an arbitrary clip shape.

abstract void

setColor(Color c) Sets this graphics context's current color to the specified color.

abstract void

setFont(Font font) Sets this graphics context's font to the specified font.

abstract void

setPaintMode() Sets the paint mode of this graphics context to overwrite the destination with this graphics context's current color.

abstract void

setXORMode(Color c1) Sets the paint mode of this graphics context to alternate between this graphics context's current color and the new specified color.

String toString() Returns a String object representing this Graphics object's value.

abstract void

translate(int x, int y) Translates the origin of the graphics context to the point (x, y) in the current coordinate system.