Objektorientierte Programmierung in Java Objektorientierte Programmierung in Java Programmieren 2 - TINF13C Matthias Diester 08.05.2014 - 14.07.2014 / DHBW Stuttgart Objektorientierte Programmierung in Java Einführung / Allgemeines Vorstellung Vorstellungsrunde Zu meiner Person: Matthias Diester Software Engineer (WebSphere Portal Server Development) Kontakt: [email protected] Objektorientierte Programmierung in Java Einführung / Allgemeines Lernziele Lernziele - Teil 1 Kennen der Grundelemente einer prozeduralen und einer objektorientierten Programmiersprache Entwerfen eines Programmdesigns (Algorithmus, Klassenhierarchie) Verwenden von Beschreibungsmethodik (Struktogramm, UML) Kennen verschiedener Datenstrukturen und ihre Verwendungsmöglichkeiten Kennen von Strukturierungsmöglichkeiten einer modernen höheren Programmiersprache und exemplarisch anwenden (Funktionen, Module, Klassen) Objektorientierte Programmierung in Java Einführung / Allgemeines Lernziele Lernziele - Teil 2 Selbständig Programme entwickeln und kodieren Systematische Fehlersuche durchführen Standard-Klassenbibliotheken anwenden Dialoganwendungen programmieren Eine Programmierumgebung beispielhaft kennen Programmierkonventionen anwenden Beurteilen/Bewerten welche Programmiertechnik in konkreten Anwendungsfällen am besten zum Ziel führt Objektorientierte Programmierung in Java Einführung / Allgemeines Lerninhalte Kenntnisse in objektorientierter Programmierung - Teil 1 Objektorientierter Programmentwurf (z. B. Klassendiagramme) Idee der objektorientierten Programmierung Klassenkonzept Operatoren Überladen von Operatoren und Methoden Objektorientierte Programmierung in Java Einführung / Allgemeines Lerninhalte Kenntnisse in objektorientierter Programmierung - Teil 2 Vererbung und Überschreiben von Operatoren Polymorphismus Template Klassenbibliotheken Speicherverwaltung (Garbage Collector) Graphische Benutzeroberäche und ereignisgesteuerte Programmierung Objektorientierte Programmierung in Java Einführung / Allgemeines Organisatorisches Vorlesung und Prüfung 11 Vorlesungen à 4 Stunden keine benotete Projektarbeit Abschluss durch Klausur Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Programmieren - allgemein Prozedurale versus Objektorientierte Programmierung Prozedurale Programmierung Teilen der Aufgabenstellung in Teilprobleme (Prozedur) Programm besteht aus der Komposition der Prozeduren Beispiele: C, Pascal Objektorientierte Programmierung Zusammenfassung von Struktur und Funktion in Objekten Programm deniert Zusammenspiel von Objekten Beispiele: Smalltalk, Java Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Idee der Objektorientierung In der objektorientierten Programmierung wird die Problemstellung durch Objekte, deren Eigenschaften und der Interaktion zwischen verschiedenen Objekten beschrieben. Damit können komplexere Problemstellungen strukturierter dargestellt und einfacher gelöst werden. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Idee der Objektorientierung Zur Beschreibung der Problemstellung in einer objektorientierten Programmiersprache werden sogenannte Klassen verwendet. Auf Basis dieser Klassen werden zur Laufzeit Objekte erzeugt. Die Klassen dienen somit als Vorlage beziehungsweise Template für Objekte. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Idee der Objektorientierung Die Kerndenition der Objektorientierung umfasst: Vererbung Datenkapselung Polymorphie Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Vererbung Die Vererbung bezeichnet die Fähigkeit, dass eine Klasse die Eigenschaften und Fähigkeiten einer anderen Klasse erben und somit übernehmen kann. In der erbenden Klasse können dann neue Funktionen zusätzlich eingeführt werden. Durch die Vererbung stehen diese Klassen dann in Beziehung zueinander. Erbt eine Klasse von mehreren Klassen so wird dies Mehrfachvererbung genannt. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Datenkapselung Die Fähigkeit der Datenkapselung bezeichnet die Möglichkeit in einer objektorientierten Sprache nur die Implementierungsdetails öentlich zu machen, welche vom Programmierer auch oen gelegt werden möchten. Damit entsteht oftmals eine klarere Struktur und sicherer Quelltext. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Polymorphie Typischerweise wird die horizontale und vertikale Polymorphie unterschieden. Die vertikale Polymorphie beschreibt die Fähigkeit in einer objektorientierten Programmiersprache in einer Klasse eine geerbte Funktionalität neu zu denieren und damit das Verhalten anders zu gestalten. Mit horizontaler Polymorphie ist gemeint, dass innerhalb einer Klasse die gleiche Funktionalität mit unterschiedlichen Parametern deniert werden kann. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Denition Klasse Klassen bestehen jeweils aus einem statischen und einem nicht-statischen Anteil. Der nicht-statische Anteil dient zur Beschreibung von Objekten die auf Basis der Klasse erstellt werden. Der statische Anteil umfasst ebenfalls Funktionen und Variablen, die jedoch nicht in die Objekt Generierung einieÿen und zur Steuerung des Programmusses genutzt werden. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Denition Objekt Ein Objekt ist ein konkretes Exemplar einer bestimmten Klasse. Durch die Klasse deniert sich der Typ des Objekts. Im typischen objektorientierten Sprachgebrauch wird dieses Objekt dann als Instanz einer Klasse bezeichnet. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Denition Objekt Ein Objekt . . . hat eine Identität. hat einen Zustand. kann Nachrichten versenden. kann Nachrichten empfangen. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Identität eines Objekts Ein Objekt wird auf Basis einer Klasse durch einen Konstruktor erstellt. Damit ist dieses Objekt vom Typ der Klasse und ist identizierbar über die Speicheradresse (Referenz) unter der es zu nden ist. Der Destruktor löscht das Objekt am Ende seiner Lebenszeit. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Zustand eines Objekts Nach der Erstellung eines Objekts haben alle Attribute dieses Objekts einen denierten Wert. Die Gesamtheit aller Attribute eines Objekts wird als Zustand des Objekts bezeichnet. Änderungen von Attributen dieses Objekts ändern nur genau seinen Zustand. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in die Objektorientierung Objekt Interaktion Ein Objekt kann eine Nachricht an ein bekanntes anderes Objekt (oder auch sich selbst) schicken und damit eine Aktion auf der Zielseite auslösen. Ein Objekt kann Nachrichten zudem von auÿen empfangen und damit intern Aktionen auslösen. Diese Aktionen werden in Methoden implementiert, die analog zur prozeduralen Programmierung Anweisungen, Zuweisungen und Konditionen beinhalten. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassungen Zusammenfassung - Klasse Die Klasse wird mit Sprachmitteln im Quelltext deniert und übernimmt zwei grundlegende Aufgaben: Sie ist der Container für alle klassenspezischen Funktionen und Attribute. Sie dient - sofern so beschrieben - zudem als Blaupause um daraus Objekte vom Typ dieser Klasse zu erzeugen. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassungen Zusammenfassung - Objekt Ein Objekt ist ein zur Laufzeit auf Basis einer Klasse erzeugtes Konstrukt mit einer Identiät (Speicheradresse), einem Zustand (Attribute) und der Möglichkeit Aktionen auszuführen und Nachrichten entgegenzunehmen. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassungen Zusammenfassung - Methode Eine Methode ist eine Sammlung von Anweisungen, Abfragen und Zuweisungen im Kontext eines Objekts. Sie übernimmt eine denierte Aufgabe und liefert ein Ergebnis. Eine statische Methode (Funktion) ist im Kontext einer Klasse eine Sammelung von Anweisungen, Abfragen und Zuweisungen, die eine gewisse Aufgabe übernimmt und ein Ergebnis liefert. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassungen Zusammenfassung - Attribut Ein Attribut ist eine Variable in einem Objekt. Diese Variable kann etwas einfaches wie einen Datentyp beinhalten oder auch eine Referenz auf ein anderes Objekt sein. Ein statisches Attribut ist analog zum nicht-statischen Attribut ebenfalls eine Variable oder Referenz, allerdings im Kontext einer Klasse. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassungen Zusammenfassung - Konstruktor/Destruktor Der Konstruktor ist eine spezielle Methode welche ein Objekt baut. Der Rückgabewert ist immer vom Typ der Klasse. Ein Destruktor ist die Methode welche zum Ende der Lebenszeit eines Objekts aufrufen wird und den Zurückbau übernimmt. Ein Destruktor muss in einer objektorientierten Programmiersprache nicht in genau dieser Art vorkommen. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Die Entstehung von Java 1990 entwickelt James Gosling aus Unmut über C++ eine neue Sprache namens Oak. Oak kommt als Interpreter im Green-OS Projekt zum Einsatz, ein System für interaktives Fernsehen. Oak kommt ab 1993 mit dem neuen Namen Java in einem weiteren Projekt zum Einsatz, einem speziellen Web Browser namens HotJava. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Die Entstehung von Java Abbildung: James Gosling Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Die Entstehung von Java Das 1995 auf der SunWorld vorgestellte HotJava Projekt führt zur Lizensierung der Java-Technologie durch Netscape. Im Dezember 1995 wird der Netscape Navigator mit Java Technologie vorgestellt, Anfang 1996 das Java Software Development Kit (JDK) in der Version 1.0. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Die Entstehung von Java Abbildung: Duke (Java Maskottchen) Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Die Entstehung von Java Es folgen 1.1 (1997), 1.2 (1998), 1.3 (2000), 1.4 (2002), 5 (2004), 6 (2006), 7 (2011) und 8 (2014) Seit 2009/2010 unter der Hoheit der Oracle Corporation Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Zielsetzung von Java Einfach, Objektorientiert und Vertraut Robust und Sicher Architekturell neutral und Portierbar Hohe Leistungsfähigkeit Interpretiert, Nebenläug und Dynamisch Im Detail zu nden unter: http://www.oracle.com/technetwork/topics/newtojava/documentation Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Genereller Aufbau Da Java eine objektorientierte Sprache ist, stellen Klassen den zentralen Baustein dieser Sprache dar. Java Quellcode wird in Textform in Dateien mit der Endung java abgelegt. Dabei gilt eine 1:1 Zuordnung zwischen Hauptklasse und Quellcode Datei, wobei der Dateiname der Klassenname sein muss. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Klassen, Bytecode und Programmausführung Java Klassen werden vom Java Compiler in sogenannten (Java-)Bytecode übersetzt. Kompilierte Java Klassen haben die Dateiendung class und heiÿen, wie die Klasse die sie beschreiben. Dieser Bytecode wird dann von der Java Virtual Machine (JVM) interpretiert und auf dem jeweiligen Zielsystem ausgeführt. Damit bietet die Sprache und die damit verbundenen Spezikationen die Möglichkeit zur Herstellung von plattform-unabhängiger Software. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Hello World in Java - Java Source Hello World Beispiel in Java 1 2 3 4 5 class HelloWorld public static { void main ( System . out . p r i n t l n ( } } String [ ] " Hello args World ! " ) ; ) { Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Hello World in Java - Class File Hexdump der kompilierten Klasse 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 00000000 00000010 00000020 00000030 00000040 00000050 00000060 00000070 00000080 00000090 000000 a0 000000 b0 000000 c0 000000 d0 000000 e0 000000 f0 00000100 00000110 00000120 00000130 ca 00 00 56 75 6e 2f 72 6f 17 6f 48 61 6a 01 6f 13 72 15 69 fe 10 16 01 6d 01 53 63 72 0c 72 65 2f 61 00 2f 6a 65 28 6e ba 00 01 00 62 00 74 65 6c 00 6c 6c 6c 76 03 50 61 61 4c 67 be 11 00 04 65 16 72 46 64 18 64 6c 61 61 6f 72 76 6d 6a 3b 00 08 06 43 72 28 69 69 2e 00 21 6f 6e 2f 75 69 61 01 61 29 00 00 3c 6f 54 5b 6e 6c 6a 19 07 57 67 6c 74 6e 2f 00 76 56 00 12 69 64 61 4c 67 65 61 01 00 6f 2f 61 01 74 69 07 61 00 32 0a 6e 65 62 6a 3b 01 76 00 1a 72 4f 6e 00 53 6f 70 2f 20 00 00 69 01 6c 61 29 00 61 0c 0c 6c 62 67 15 74 2f 72 6c 00 1d 13 74 00 65 76 56 0f 0c 48 00 64 6a 2f 4c 72 50 69 61 05 0a 00 3e 0f 01 61 01 48 00 65 1b 01 65 53 6a 65 72 6e 6e 00 00 14 01 4c 00 2f 00 65 07 6c 00 00 63 79 61 61 69 74 67 06 06 07 00 69 04 6c 0a 6c 00 6c 1c 10 74 73 76 6d 6e 6c 2f 00 00 00 03 6e 6d 61 53 6c 08 6f 01 6a 01 74 61 3b 74 6e 53 00 0f 15 28 65 61 6e 6f 6f 07 20 00 61 00 65 2f 01 53 01 74 00 09 07 29 4e 69 67 75 57 00 57 0a 76 10 6d 69 00 74 00 72 00 |.......2........| |................| |..... < init >...() | | V ... Code ... LineN | | umberTable ... mai | | n ...([ Ljava / lang | |/ String ;) V ... Sou | | rceFile ... HelloW | | orld . java .......| |......... Hello W | | orld !...........| | HelloWorld ... jav | |a/ lang / Object ...| | java / lang / System | |... out ... Ljava / i| |o/ PrintStream ;..| |. java / io / PrintSt | | ream ... println ..| |.( Ljava / lang / Str | | ing ;) V . ........| Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Hello World in Java - Bytecode Dekompilierter Bytecode der Klasse 1 2 3 4 5 6 7 8 9 10 11 12 13 Compiled from " H e l l o W o r l d . j a v a " c l a s s HelloWorld extends java . lang . Object { HelloWorld () ; Code : 0 : aload_0 1 : i n v o k e s p e c i a l #1; // Method j a v a / l a n g / O b j e c t ."< i n i t >":()V 4: return p u b l i c s t a t i c v o i d main ( j a v a . l a n g . S t r i n g [ ] ) ; Code : 0 : g e t s t a t i c #2; // F i e l d j a v a / l a n g / System . out : L j a v a / i o / P r i n t S t r e a m ; 3 : l d c #3; // S t r i n g H e l l o World ! 5 : i n v o k e v i r t u a l #4; // Method j a v a / i o / P r i n t S t r e a m . p r i n t l n : ( L j a v a / lang / String ; )V 14 8: return 15 16 } Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Schlüsselwörter abstract case continue enum for instanceof new return switch transient assert catch default extends if int package short synchronized try boolean char do nal goto interface private static this void break class double nally implements long protected strictfp throw volatile byte const else oat import native public super throws while Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Schlüsselwörter Namensräume und Vererbung: class, extends, implements, import, interface, package, super, this Modizierer: abstract, nal, native, private, protected, public, static, strictfp, synchronized, transient, volatile Steuerung: assert, break, case, continue, default, do, else, for, if, switch, while Typen: boolean, byte, char, double, oat, int, long, short Exception: catch, nally, throw, throws, try Sonstiges: enum, instanceof, new, return, void Ungenutzt: const, goto Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Zugrismodizierer Zugriseigene modizierer Klasse public protected (leer) private ja ja ja ja Klasse im Unterklasse Klasse im gleichen im anderen anderen Package Package Package ja ja ja nein ja ja nein nein ja nein nein nein Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Klassen Denition 1 2 3 4 [ i m p o r t < c l a s s >] [ static i m p o r t < f i e l d >] [ < m o d i f i e r >] [ final e x t e n d s < c l a s s >] 5 6 7 8 9 10 . . . ] ] | abstract ] [ strictfp ] class <Name> [ [ i m p l e m e n t s < i n t e r f a c e >[ , < i n t e r f a c e > { −b l o c k >] [ < v a r i a b l e − d e c l a r a t i o n >] [ < method − d e c l a r a t i o n >] [ < i n n e r − c l a s s − d e f i n i t i o n >] [< i n n e r −i n t e r f a c e − d e f i n i t i o n [< s t a t i c >] } Die Sichtbarkeitsmodizierer private und protected dürfen nicht verwendet werden. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Interface Denition 1 2 3 4 5 [ i m p o r t < c l a s s >] [ < m o d i f i e r >] [ abstract ] e x t e n d s < i n t e r f a c e >] [ strictfp ] interface <Name> [ { [ < p r o t o t y p e −method − d e c l a r a t i o n >] } Die Sichtbarkeitsmodizierer private und protected dürfen nicht verwendet werden. Das Schlüsselwort abstract ist zulässig aber überüssig. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Variablendeklaration (Klassenkontext) 1 [ < m o d i f i e r >] [ final ] [ static ] <name> [= < i n i t a l −v a l u e >] [ transient ] [ volatile ] <Type> Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Syntax - Methodendeklaration 1 [ < m o d i f i e r >] ] 2 3 [ final ] [ synchronized ] . . . ] ) [ static ] [ abstract ] [ native ] < R e s u l t −Type> <name> ( [ strictfp [< argument> { [< e x p r e s s i o n > . . . ] } Eine Methode die abstract ist, kann nicht nal, native, private oder static sein. Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Operatoren - Teil 1 ++, −− ++, −−, +, −, ~, ! new (Cast) ∗, /, % +, − <<, >>, >>> <, <=, >, >= instanceof Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Einführung in Java Operatoren - Teil 2 ==, ! = & | && || ?: =, + =, − =, ∗ =, / =, %=, &=, =, | =, <<=, >>=, >>>= Objektorientierte Programmierung in Java Programmieren, Objektorientierung und Java Zusammenfassung Zusammenfassung Idee und Konzepte der Objektorientierung Entstehung von Java Hello World! in Java Schlüsselwörter, Syntax und Operatoren Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Datentypen In Java ist es möglich einfache Datentypen als Variablen zu benutzen. Diese einfachen Datentypen stellen daher im Kontext der Objektorientierung eine gewisse Sonderstellung dar. Für jeden dieser primitiven Datentypen gibt es allerdings auch eine Objektentsprechung. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Datentypen boolean (true, false) char (\u 0000..\uFFFF ) byte (−128..127) short (−32768..32767) int (−2147483648..2147483647) long (−263 ..263 − 1) oat (1.4 × 10−45 ..3.4 × 1038 ) double (5 × 10−324 ..1.8 × 10308 ) Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Vererbung Java unterstützt keine direkte Mehrfachvererbung, da diese typischerweise aus objektorientierter Sichtweise zu Mehrdeutigkeiten führen kann die unerwünscht sind. Daher wurden in Java sogenannte Interfaces (Schnittstellen) eingeführt, welche Sachverhalte abbildbar machen, die eine Mehrfachvererbung benötigen würden. Diese Interfaces enthalten keinen implementierenden Quelltext, sondern lediglich Methoden Prototypen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Automatische Speicherverwaltung In Java wurde bewusst auf Destruktoren verzichtet, da diese oft zu Problemen führen. Daher wurde eine automatische Speicherverwaltung eingeführt. Ein Mechanismus namens Garbage Collector (GC) räumt nicht mehr benötigte Objekte aus dem Speicher. Ein explizite Destruktion von Objekten ist daher nicht möglich. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Strings Neben den primitiven Datentypen nehmen Strings eine Sonderstellung in Java ein. Aus Gründen der Bequemlichkeit darf der Plus Operator (+) auf Strings angewendet werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Pointer vs. Reference In Java existiert kein Konzept für allgemeine Pointer (Zeiger), sondern immer nur typsichere Pointer die Referenz genannt werden. Eine Referenz zeigt damit immer auf ein Objekt vom Typ der Referenz oder auf das spezielle Literal null. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Besonderheiten - Call by Value Es existiert kein Call by Reference in Java, auch wenn z. B. mit Referenzen in Methoden Parametern gearbeitet wird. Dies sind dann Kopien der Referenzen. Alle Methodenaufrufe, ob nun mit primitiven Datentypen oder Objekt Referenzen werden in Java mit Call-By-Value gelöst. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Packages Alle Klassen in Java gehören zu einem Package. Wird dieses nicht explizit benannt, so wird diese Klasse in das Default-Package eingeordnet. Eigene Klassen sollten immer einem selbst denierten Namensraum zugeordnet werden. Typischerweise wird dafür eine umgekehrte URL Variante verwendet. Beispiel: de.dhbw.str.project Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen Über Konditionen wird der Programmuss gesteuert: if - then if - then - else switch - case assert Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen If-Then 1 2 3 4 5 6 7 if ( l o g g e r . isDebugEnabled () l o g g e r . debug ( if ( ( hole > = ) logging 0 ) && ( h o l e < parList [ hole ] isValid " Debug 19) message . " ) ) ; { = par ; true ; } Der Ausdruck im if muss vom Typ boolean sein, beziehungsweise Boolean beim automatischen Unboxing ab Java 5. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen If-Then-Else 1 2 3 4 5 6 7 8 9 10 11 12 13 if ( ( v a l u e > min ) && ( v a l u e < max ) inRange = } else true ; { inRange = foobar ( false ; value ) ; } if ( x == 1 ) amount = 1 0 0 0 0 ; else if ( x == 2 ) amount = 2 0 0 0 0 ; else amount = 0; ) { Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen If-Then-Else 1 2 3 4 5 if ( a > 0 if ( ) a > 100 ) System . out . p r i n t l n ( "Ok" ) ; else System . out . p r i n t l n ( " Value : " + a ) ; Ein Dangling-Else in Java gehört per Denition zum innersten if. Das Konstrukt sollte jedoch vermieden werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen Switch-Case 1 2 3 4 5 6 7 switch ( level ) { case 1: desc = " Level 1" ; break ; case 2: desc = " Level 2" ; break ; default : d e s c = " Unknown " ; break ; } Ohne break im case Block wird bis zum nächsten break oder switch Ende weitergemacht. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Konditionen Assert 1 2 3 assert ( string != null assert value . isInRange () && : string . length () > 0 " Value out of ) ; range " ; Assertions müssen per JVM Parameter -ea oder -enableassertions explizit eingeschaltet werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Schleifen In Java existieren vier Schleifenvarianten: for: for ( <init>; <condition>; <post-loop> ) while: while ( <condition> ) do: do - while ( <condition> ) foreach: for ( <Type> <Name> : <list> ) Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Schleifen Beispiel for 1 2 3 for ( int foobar ( } i =0; i ) ; i <100; i++ ) { Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Schleifen Beispiele while 1 2 3 4 5 6 int i =5; while ( i > 0 foobar ( i } −−; i ) ) ; { Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Schleifen Beispiele do 1 2 3 4 5 6 7 8 9 int do i = 0; { i = if ( obj . getValue () ; i == 0 foobar ( } while ( i ) " no != 0 wombat " ) ; ) ; Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Schleifen Beispiele foreach 1 2 3 4 5 String [ ] for ( String foobar ( } array = new entry entry ) ; : String [ ] array ) { { " 1 s t " , " 2 nd " , " 3 r d " }; Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Exceptions Exceptions bilden eine weitere Form der Programmsteuerung. Darüber hinaus gibt es zusätzlich noch das Error Konzept. Sowohl Error als auch Exception werden in Java unter der gemeinsamen Oberklasse Throwable zusammengefasst. Bei den Exceptions wird zudem zwischen geprüften und ungeprüften Exceptions unterschieden. Neben den bereits in Java eingebauten Exceptions können beliebige weitere Exceptions deniert werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Exceptions denieren 1 2 3 4 5 6 7 8 9 10 11 12 13 public class UnexpectedBehaviourException extends Exception { private public String reason ; UnexpectedBehaviourException ( String super () ; t h i s . reason = reason ; } public String return } } getReason () reason ; { reason ) { Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Exceptions werfen 1 public 2 3 4 5 6 7 8 9 10 11 static void createFoobar () UnexpectedBehaviourException // ... int value if ( value < 0 throw = new Value " // } throws { ... process () ; ) UnexpectedBehaviourException ( ) ; " Unexpected Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Exceptions abfangen 1 2 3 4 5 6 7 8 9 10 11 12 public // static int i ; try { i } = } // readValue ( InputStream = inputStream . read () ; catch i } void ... ... ( IOException − 1; e) { inputStream ) { Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Exceptions und Finally Block 1 2 3 4 5 6 7 8 9 10 11 try i { = inputStream . read () ; // } ... catch ( IOException logging . error ( } finally try e) { " IOException occurred { { inputStream . c l o s e () ; } } } catch ( IOException ignored ) { ... " ) ; Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Programmuss - Methodenaufruf Eine Methode kann immer nur in einem konkreten Namensraum existieren und ausgeführt werden. Im statischen Kontext muss deshalb der Name der Klasse mit einem Punkt vorangestellt werden. Wird diese Klasse weggelassen, gilt die aktuelle Klasse als Namensraum. Beispiel: int i = Integer.parseInt( str ) Bei Objekten muss analog das entsprechene Objekt per Punkt vorangestellt werden. Wird es weggelassen, so wird im aktuellem Objektnamensraum gesucht. Beispiel: int len = string.length() Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Erzeugen von Objekten mit new Objekte werden in Java mittels des reservierten Schlüsselwort new erzeugt. Auf new folgt dann der Konstruktor der entsprechenden Klasse der verwendet werden soll. Beispiele: String s = new String(); Integer i = new Integer( 42 ); Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Anlegen und Nutzen von Arrays Das Schlüsselwort new wird ebenfalls zur Erzeugung von Arrays genutzt. Arrays werden in Java mit einem Initialwert erzeugt: bei zahlenbasierten Arrays ist dies 0, für boolean-Arrays false und bei Arrays von Referenzen null. long[] array = new long[10]; long array[] = new long[] { 1,2,3,4,5,6 }; array[3] = 42; long value = array[0]; Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Vererbung mit extends Soll eine Klasse von einer anderen Klasse erben, muss das Schlüsselwort extends bei der Klassendeklaration verwendet werden. In Java kann eine Klasse nur von einer anderen nicht-nalen Klasse ableiten. Beispiel: class Worker extends AbstractWorker Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Java (Fortsetzung) Implementierung von Interfaces mit implements Eine Klasse kann mittels dem Schlüsselwort implements beliebig viele Interfaces implementieren. Verschiedene Interfaces werden durch Komma getrennt nach dem Schlüsselwort bei der Klassendeklaration aufgeführt. Beispiel: class Worker implements Comparable, Serializable Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Was ist Eclipse? Bei Eclipse handelt es sich um eine Rich Client Platform (RCP). Damit lassen sich universelle grasche Benutzeroberächen erstellen. Eclipse wird oft synonym für die Entwicklungsumgebung für Java verwendet. Das eigentliche Integrated Development Environment (IDE) für die Software Entwicklung mit Java ist streng genommen nur ein Plug-In im Eclipse Framework. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Weitere IDEs für Java Es gibt eine groÿe Auswahl an Entwicklungsumgebungen für Java. Die Oracle Cooperation stellt z. B. NetBeans zur Verfügung. Auÿerdem gibt es diverse Open-Source IDEs für Java: Cube-J, DrJava, . . . Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Kurze Geschichte IBM entwickelt Eclipse ab Ende der 1990er-Jahre einen Ersatz für die proprietäre, Smalltalk-basierte Entwicklungsumgebung Visual Age. Ab 2001 wurde daraus eine Open Source-Unternehmung um weitere Projekt Partner in die Entwicklung zu holen. Seit 2004 wird die Entwicklung von einer Non-Prot-Organisation mit dem Namen Eclipse Foundation gesteuert. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Eclipse Workspace Zentraler Baustein in Eclipse stellt der sogenannte Workspace da. Er wird direkt im Dateisystem abgelegt und beinhaltet Projekte und Metainformationen. Es können beliebig viele Workspaces in Eclipse angelegt werden. Pro laufender Eclipse Instanz kann immer nur ein Workspace aktiv sein. Der Workspace ist für den jeweiligen Benutzer von Eclipse vorgesehen und wird typischerweise nicht in ein Versionskontrollsystem eingestellt. In Metainformationen können hier z. T. benutzerspezische Einstellungen gespeichert werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Perspectives Die Perspektiven (engl. perspectives) stellen die unterschiedlichen Aufgabenbereiche im Eclipse Framework dar. Für die Java Entwicklung gibt es die Java Perspektive. Weitere interessante Perspektiven sind z. B.: Java EE (Java Enterprise Edition Entwicklungsumgebung) C/C++ (Entwicklungsumgebung für C/C++) Repository Explorer (CVS/Subversion Explorer) ... Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Views Es existieren Perspektiven-spezische und universelle Views. Ein View stellt ein Element der Eclipse Oberäche dar, das beliebig platziert werden kann und eine Aufgabe übernimmt. Der wichtigste View ist i. d. R. der Editor. Weitere Views sind z. B.: Console (Feld mit der Ausgabe von StdOut/StdErr) Tasks (TODO Liste) Project Explorer (Liste der Projekte im Workspace) ... Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Eclipse Java Projekt Im Eclipse Workspace werden Projekte abgelegt. Viele Perspektiven bieten spezialisierte Projekte für ihre Aufgabe an. Im Falle von Eclipse als Java IDE ist dies das Java Projekt. Ziel eines Java Projekts kann z. B. eine Bibliothek sein oder auch das Hauptprogramm. Typischerweise werden in einem groÿen Entwicklungsprojekt mehrere Projekte verwendet, um die Aufgabenstellung in Teilprojekte zu zerlegen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Source Tree im Java Projekt In einem Java Projekt kann ein Source Tree angelegt werden. Darin wird dann die Package Struktur mit dem Java Quellcode abgelegt. Nur Quellcode in den Source Trees wird für die automatische Projektgenerierung angezogen. Eine gute Herangehensweise ist das Anlegen eines Source Trees src für den Hauptquellcode und einen Source Tree test für die Testklassen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Anlegen von Klassen Eine Klasse angelegt werden in dem im Projekt Explorer im Kontextmenü der entsprechende Menüpunkt ausgewählt wird. Im dann erscheinden Dialog werden alle initial wichtigen Felder abgefragt. Alternativ kann auch einfach ein Klassenname im bestehenden Quelltext angegeben werden. Über die Fehlermeldung kann dann die entsprechende Klasse ebenfalls angelegt werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Einführung in Eclipse Hello World Eclipse Projekt File - New - Java Project File - New - Class Package (z. B. de.dhbw.str.helloworld) und Klassennamen (HelloWorld) eingeben Main Methode schreiben Projekt per: Run - Run starten Objektorientierte Programmierung in Java Java und Eclipse (IDE) Nützliche Shortcuts in Eclipse Integrierte Autovervollständigungen 'for' für For - Schleifen Varianten 'main' für Main Methode 'syso' für System.out.println() 'syse' für System.err.println() 'lazy' für Lazy Creation 'switch' für Switch Case Block Objektorientierte Programmierung in Java Java und Eclipse (IDE) Nützliche Shortcuts in Eclipse Launch Congurations In Launch Conguration werden alle Informationen zusammengefasst, die für die Ausführung einer gewissen Aufgabe notwendig sind. Eine solche Aufgabe kann z. B. das Starten eines Java Programms oder das Ausführen von automatischen Test Fällen sein. Eine Launch Conguration kann entweder in den Workspace Metainformationen oder lokal im Dateisystem abgelegt werden. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Nützliche Shortcuts in Eclipse Debug Modus Eine Java Application Launch Conguration kann immer auch im Debug Modus in Eclipse gestartet werden. Damit ist es möglich ein Programm schrittweise abzuarbeiten und die aktuellen Variablen Belegungen im laufenden Programm zu beobachten. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Nützliche Shortcuts in Eclipse Shortcuts im Editor Strg + D . . . Zeile löschen Strg + Leertaste . . . Autovervollständigung Alt + Umschalt + R . . . Aktuelles Element umbenennen Strg + Umschalt + O . . . Importe neu organisieren Strg + Umschalt + F . . . Formatiere den Quelltext Strg + Umschalt + C . . . Zeile (aus-)kommentieren Objektorientierte Programmierung in Java Java und Eclipse (IDE) Nützliche Shortcuts in Eclipse Shortcuts Allgemein F11 . . . Aktuelle Editor Auswahl im Debug Modus starten Strg + 1 . . . Quick Help Strg + F11 . . . Aktuelle Editor Auswahl laufen lassen Strg + Umschalt + T . . . Nach Klasse suchen Strg + Umschalt + R . . . Ressource (z. B. Datei) suchen Objektorientierte Programmierung in Java Java und Eclipse (IDE) Programmier Übungen Einfache Beispielprojekte zum Kennenlernen Hello World! Hello <Name>! 99 Bottles of Beer Objektorientierte Programmierung in Java Java und Eclipse (IDE) Programmier Übungen Beispiel 1: Hello World! Als Ausgabe des Programm soll auf der Console (bzw. im Console View) der Text Hello World! oder etwas ähnliches ausgegeben werden. Auch das Hello World Projekt soll seine Klassen mit passenden Package Namen versehen. Ziel: Java Projekt in Eclipse SDK anlegen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Programmier Übungen Beispiel 2: Hello <Name>! Ein neues Projekt, dass zum Ziel hat statt dem Text World einen veränderlichen Text anzuzeigen. Im einfachsten Fall soll der anzuzeigende Text per Argument dem Java Programm zur Verfügung gestellt werden. In einer erweiterten Fassung soll das Programm nun prüfen, ob ein Argument übergeben wurden ist. Gibt es kein Argument, so soll das Programm dem Benutzer auf der Console nach einem Eingabe Text fragen. Ziel: Launch Congurations in Eclipse nutzen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Programmier Übungen Beispiel 3: 99 Bottles of Beer Ein weiteres Projekt anlegen, welches den Text von 99 Bottles of Beer auf die Console schreibt. Ziel: Nutzung von Schleifen und die Erkenntnis das viele Wege zum Ziel führen. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Programmier Übungen Beispiel 3: 99 Bottles of Beer (Text) 99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall. ... 2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall. 1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall. Objektorientierte Programmierung in Java Java und Eclipse (IDE) Zusammenfassung Zusammenfassung Konzepte der Programmusssteuerung in Java (Konditionen, Schleifen und Exceptions) Zielsetzung des Eclipse Frameworks Grundsätzlicher Aufbau von Eclipse als Java IDE (Perspektiven, Views und Plug-Ins) Launch Congurations und Debug Modus Projekte in Eclipse anlegen Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Benutzerschnittstellenbibliotheken in Java (AWT) Wie auch in anderen Programmiersprachen üblich verfügt Java per Spezikation bereits über integrierte Bibliotheken zum Bau von graschen Benutzeroberächen (GUIs). Die historisch gesehen erste API dafür war das Abstract Window Toolkit (AWT), welches i. d. R. heute nicht mehr in Reinform eingesetzt wird. Klassen die zu AWT gehören liegen im Package java.awt. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Benutzerschnittstellenbibliotheken in Java (Swing) Auf AWT folgte Swing, welches zu groÿen Teilen intern auf AWT aufbaut aber deutlich mehr Funktionalität in Form von mehr Oberächenelementen implementiert. Swing ist Teil der Java Foundation Classes (JFC). Swing spezische Klassen unterscheiden sich von ihrem AWT Pendent durch ein vorangestelltes J und benden sich in der Standard Java Package Struktur unterhalb von javax.swing. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Hello World mit Swing 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import j a v a x . s w i n g . JFrame ; import javax . swing . JLabel ; public class public HelloWorld static JFrame void { main ( S t r i n g [ ] j F r a m e = new args ) { JFrame ( ) ; jFrame . s e t T i t l e ( " H e l l o World ! " ) ; j F r a m e . s e t D e f a u l t C l o s e O p e r a t i o n ( J F r a m e . EXIT_ON_CLOSE ) ; jFrame . s e t S i z e (640 , 480) ; jFrame . s e t V i s i b l e ( t r u e ) ; JLabel jLabel j F r a m e . add ( } } = new jLabel JLabel ( ) ; " Hello World " ) ; Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Einteilung von Swing Komponenten Grundsätzlich werden Swing Komponenten in zwei Kategorien unterschieden: atomare Komponenten: Komponenten zur Darstellung von Oberächeninhalten, wie z. B. ein Knopf (Button) oder ein Textfeld (Text Field). Container Komponenten: Nehmen andere Container Komponenten und atomare Komponenten auf und ordnen diese in sich an. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Layoutmanager Container Komponenten nutzen sogenannte Layouts um die sich in ihnen bendlichen Komponenten anzuordnen. In Swing sind bereits die wichtigsten Layout Konzepte implementiert: FlowLayout GridLayout BorderLayout GridBagLayout ... Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Beispiel für Layout Nutzung 1 2 3 4 5 6 7 8 9 10 11 12 private void i n i t i a l i z e () { ... s e t L a y o u t ( new B o r d e r L a y o u t ( ) ) ; pane . add ( new J L a b e l ( "Oben" ) , B o r d e r L a y o u t .NORTH ) ; pane . add ( new J L a b e l ( " M i t t e " ) , B o r d e r L a y o u t . CENTER ) ; pane . add ( new J L a b e l ( " Unten " ) , B o r d e r L a y o u t .SOUTH ) ; } ... Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Ereignissteuerung Neben den graschen Elementen gehört die Ereignissteuerung zu den Aufgaben beim Entwicklen von Benutzeroberächen. Damit lassen sich Ereignisse wie z. B. ein Maus Klick mit einer Aufgabe verbinden. In Java werden solche Ereignisse unter dem Überbegri Action zusammengefasst. Bei Komponenten können sogenannte EventListener registriert werden, die dann im Falle eines Ereignisses kontaktiert werden. Soll auf ein bestimmtes Ereignis reagiert werden, so muss einfach nur die dafür vorgesehene Methode des EventListener implementiert werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Beispiel für MouseListener 1 2 3 4 5 6 7 8 9 10 11 12 public class public if ( void ExitOnDoubleClick m o u s e C l i c k e d ( MouseEvent e . getClickCount () > 1 System . out . p r i n t l n ( System . e x i t ( 0 ) ; } } ... } implements ) e) MouseListener { { " Double Click ... " ) ; { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzeroberächen in Java Beispiel für JFrame Zentrierung 1 2 3 4 5 6 7 8 9 10 11 12 13 private void centerOnScreen () { ... Dimension dim = Toolkit . getDefaultToolkit () . getScreenSize () ; int screenWidth = ( i n t ) int screenHeight int width = getWidth ( ) ; int height = dim . g e t W i d t h ( ) ; = ( int ) getHeight () ; setBounds (( screenWidth − ( screenHeight width , } dim . g e t H e i g h t ( ) ; width ) − height ) ; / 2, height ) / 2, Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Programmierbeispiel 4 - Hello GUI Ein neues Projekt erzeugen in dem wir das klassische Hello World Beispiel als GUI schreiben. Es soll ein Fenster mit dem Schriftzug Hello World angezeigt werden. In einer erweiterten Fassung soll ein EventListener darauf achten, wann wir einen Doppelklick auf den Hello World-Schriftzug ausführen, um darauf hin das Programm zu beenden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Programmierbeispiel 5 - Hello Layout In einem weiteren Projekt soll eine Klasse GUI geschrieben werden, die von JFrame erbt. Als Layout für das ContentPane soll BorderLayout verwendet werden, um verschiedene Text Labels an verschiedene Stelle der Oberäche zu platzieren. Das Projekt soll dann um eine Klasse MainPanel erweitert werden, die von JPanel erbt und das FlowLayout nutzt. Darin werden Text Labels und Text Felder platziert. Objektorientierte Programmierung in Java Java, Swing und Eclipse Zusammenfassung Zusammenfassung AWT und Swing als GUI Frameworks Container, Components und Layouts Ereignissteuerung mit Actions und Listenern Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Kurze Einführung zu Generics Mit Generics ist es möglich Klassen, Interfaces und Methoden zu typisieren. In der Implementierung können dann generische Parameter genutzt werden, die erst beim Instanziieren zur Laufzeit genauer speziziert werden müssen. Damit sind auf Basis einer Klasse mehrere typisierte Ausprägungen möglich. Beliebter Ansatzpunkt von Generics sind Container Klassen, also all diese Klassen die Objekte in sich aufnehmen. Mit Generics kann die Implementierung allgemein gehalten werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Kurze Einführung zu Generics Typische Beispiele für die Nutzung von Generics bei Container Klassen. LinkedList<String> list = new LinkedList<String>(); List<Integer> numbers = new ArrayList<Integer>(); Map<Byte,String> cache = new HashMap<Byte,String>(); Generische Container Klassen sind erst ab der Java Version 1.5 möglich. Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Kurze Einführung zu Java Input/Output Verarbeitung Im Rahmen der Java Foundation Classes existieren eine Reihe von Klassen für das Themenfeld der Eingabe- und Ausgabeverarbeitung. Vereinfacht dargestellt, gibt es zwei Konzepte, welche miteinander in Verbindung stehen. InputStream/OutputStream - Representieren alle byte-basierten Datentransfers, wie z. B. bei Netzwerkübertragungen. Reader/Writer - Zielen auf die Verarbeitung von Datenströmen ab, welche menschenlesbare Texte beinhalten und daher Konzepte der Zeichenkodierung unterstützen. Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Kurze Einführung zu Java Input/Output Verarbeitung 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 String line = null ; BufferedReader try reader = null ; { reader while = new (( l i n e B u f f e r e d R e a d e r ( new = ... } } finally if { ( reader try != null ) { reader . close () ; } catch // } } ( IOException Ignored FileReader ( f i l e ) ) ; reader . readLine () ) e) { != null ) { Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Programmierbeispiel 6 - Quiz Anwendung In diesem Programmierbeispiel soll eine Quiz Anwendung programmiert werden. Der Benutzer bekommt eine Frage gestellt und eine Auswahl präsentiert. Wird die richtige Antwort gegeben, erscheint die nächste Frage. Dies wird so lange wiederholt bis die angegebene Anzahl von Fragen abgearbeitet sind. Objektorientierte Programmierung in Java Java, Swing und Eclipse Programmier Übungen Erkenntnisse aus der Programmieraufgabe - Quiz Aufwand für die GUI kann erheblich sein Oberächen Code und Logik vermischen recht schnell Das Auslagern von EventListener in eigene Klasse führt zu erhöhter Komplexität durch zusätzliche Referenzen und oenere Zugrismodizierer Soll auf eine Komponente von verschiedenen Stellen zugegrien werden, sind zusätzliche Getter-Methoden notwendig Objektorientierte Programmierung in Java Java, Swing und Eclipse Nützliche Eclipse Shortcuts Shortcuts im Editor Shift + Alt + I . . . Inline der aktuellen Auswahl (Cursor Postition), welche z. B. Methoden Deklaration, statisches nales Field (Konstante) oder lokale Variable Shift + Alt + M . . . Extrahiere die aktuelle Auswahl (markierter Text) in eine neue Methode. Eclipse versucht dabei alle notwendigen Rahmenparameter abzuschätzen, z. B. Methoden Rückgabewert und die Parameter Shift + Alt + L . . . Extrahiere die aktuelle Auswahl (Cursor oder markierter Text) in eine neue denierte Variable Objektorientierte Programmierung in Java Java, Swing und Eclipse Nützliche Eclipse Shortcuts Shortcuts im Editor Shift + Strg + G . . . Liste alle Referenzen der aktuellen Auswahl (Cursor) im Workspace. Das ist z. B. praktisch um zu sehen, wo eine Klasse, Methode oder Variable im aktuellen Workspace aktuell verwendet wird. Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc Styleguide/Konventionen In der Praxis wird Quellcode immer von einem Team an Entwicklern programmiert. Typischerweise wird sich deshalb auf einen Stil für den Source Code entschieden. Gänge IDEs unterstützen die reine Formatierung durch z. B. Auto-Formater. Darüber hinaus werden oft auch gewisse Konventionen für den Quelltext selbst deniert. Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc Vorschläge für gute Konventionen In Klassen immer die gleiche sortierte Reihenfolge einhalten (Member, Konstruktor, Methoden, Innere Klassen, . . . ). I. d. R. nur ein return Statement pro Methode. Es werden keine Error oder Throwable Objekte abgefangen. Keine benamte Sprungmarken mit continue verwenden (Pseudo Goto). Kritische Schleifen mit Forever-Loop Protektoren versehen. Keine String Verkettung mit dem Plus Operator in Schleifen oder gröÿeren Texten. Im catch-Block nicht generell auf Exception abfangen. Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc JavaDoc JavaDoc ist eine einfache Variante Dokumentation für Quellcode Komponenten direkt im Quellcode zu schreiben, um daraus einheitliche Dokumente zu erstellen. Der im JDK mitgelieferte JavaDoc Compiler erzeugt aus dem verfügbaren Java Quellcode eine HTML-basierte Dokumentation, bei der die einzelnen Klassen auch inhaltlich verknüpft werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc JavaDoc - Beispiel Klasse 1 2 3 4 5 6 7 8 9 10 11 12 13 /∗ ∗ ∗ M a i n C l a s s w i t h { @ l i n k #m a i n ( S t r i n g [ ] ) } m e t h o d ∗ t h a t d i s p l a y s t h e s o n g t e x t o f "99 B o t t l e s o f ∗ Beer " . ∗ ∗ @version 1.0 ∗ ∗ @author Matthias D i e s t e r ∗ ∗/ public ... } class MainClass { Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc JavaDoc - Beispiel Klassenvariable/Member/Field 1 2 3 4 5 6 ... /∗ ∗ Initial private ... start final value static int for the song . ∗/ INITIAL_NUMBER_OF_BOTTLES = 99; Objektorientierte Programmierung in Java Java, Swing und Eclipse Styleguide/Konventionen und JavaDoc JavaDoc - Beispiel Methode 1 2 3 4 5 6 7 8 9 10 11 12 /∗ ∗ ∗ I n t e r n a l method t h a t p r i n t s one s t r o p h e o f ∗ t h e s o n g t e x t w i t h t h e g i v e n number o f ∗ bottles . ∗ ∗ @param b o t t l e s ∗ An i n t e g e r v a l u e w i t h t h e n u m b e r o f ∗ b o t t l e s t o be u s e d i n t h i s s t r o p h e . ∗/ private ... } static void printStrophe ( int bottles ) { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Innere Klassen Um die Gesamtanzahl an Klassen nicht unnötig anwachsen zu lassen, können für einfache Klassen wie z. B. EventListener Implementierungen so genannte innere Klassen verwendet werden. Je nach Anwendungsfall innerhalb einer Klasse, können innere Klassen statisch oder nicht-statisch kodiert werden. Zudem sind alle Sichtbarkeitsmodizierer inklusiver ihrer Implikationen zugelassen. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Beispiel Innere Klasse 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class GUI extends JFrame { ... private void i n i t i a l i z e () x y z . a d d M o u s e L i s t e n e r ( new { MouseHandler ( ) ) ; } private public ... } ... } } class void MouseHandler implements m o u s e C l i c k e d ( MouseEvent MouseListener e) { { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Anonyme innere Klassen Eine zusätzliche Spezialität stellen so genannte anonyme innere Klassen dar. Dies sind Klassen ohne Namen, welche im Rahmen ein Anweisung erstellt und implementiert werden. Sie gelten nur für den Kontext/Scope in dem sie erstellt werden, allerdings können Objekte dieser Klassen wie andere Objekte auch durch return Statements oder als Argument weitergereicht werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Beispiel Innere Klasse 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class GUI extends JFrame { ... private void i n i t i a l i z e () x y z . a d d M o u s e L i s t e n e r ( new public ... } ... }) ; } } void { MouseListener () m o u s e C l i c k e d ( MouseEvent e) { { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Lazy Creation Mit Lazy Creation wird der Ansatz bezeichnet Objekte erst zu dem Zeitpunkt zu erstellen, zudem diese das erste Mal benötigt werden. Damit lässt sich typischerweise das Anstart Verhalten von Programmen oder Oberächen beschleunigen und Platz im Speicher sparen. Nachteile des Verfahrens sind die etwas schlechtere Laufzeit Performance und das Kapseln der Objekt Referenz durch eine Zugris Methode (Getter). In aufwändigeren Oberächen ist zudem auf Nebenläugkeitseekte zu achten. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Lazy Creation in GUI Klassen Lazy Creation kann beispielsweise in GUI Klassen verwendet werden, wenn . . . die Beschreibung einer Komponente aufwändiger wird. die Referenz dieser Komponente von anderen benötigt wird. das Auslagern die Übersichtlichkeit verbessert. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Nutzung von Container Komponenten Die Klasse JFrame stellt i. d. R. die Hauptcontainer Klasse für eine Oberächenanwendung dar. Zur besseren Abgrenzung sollten für zusammengehörige Oberächenelemente (Buttons, Labels, . . . ) ein eigener Container verwendet werden. Dazu kann die Klasse JPanel verwendet werden. Wird die Beschreibung einer Container Komponente zu komplex oder zu aufwändig, sollte diese Komponente in eine eigenständige Klasse ausgelagert werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) EventListener Soll auf Ereignisse reagiert werden, muss ein entsprechender EventListener bei der Komponente registriert werden. Beispiele für häug verwendete Listener sind z. B.: ActionListener KeyListener MouseListener WindowListener Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) EventListener Beispiele - ActionListener 1 2 3 4 5 private public class void OkButtonAction implements JOptionPane . showMessageDialog ( n u l l getTextField () . getText () . trim () } } ActionListener actionPerformed ( ActionEvent e) { ," Hello + "!") ; " + { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) EventListener Beispiele - KeyListener 1 2 3 4 5 6 7 8 9 10 11 private public class TextFieldKeyListener void k e y P r e s s e d ( KeyEvent void k e y R e l e a s e d ( KeyEvent implements e) { } public e) refreshOkButtonStatus () ; } public } } void keyTyped ( KeyEvent e) { { KeyListener { Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Non-GoF Factory Method-Pattern In der Praxis weitverbreitet ist die einfachste Form des Factory Method-Patterns, bei dem eine statische Methode ein Objekt eines speziellen Typs baut und als Ergebnis zurückliefert. Vererbung und Polymorphismus kommen dabei nicht zur Anwendung. Die GoF konforme Variante folgt später. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Non-GoF Factory Method-Pattern - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 public static final Car Car car buildBaseGolf () = new car . setManufacturer ( "VW" car . setModel ( ) ; " Golf " car . setClassName ( car . setType ( car . setWidth ( car . setHeight ( return } car ; ) ; C a r . CLASS_COMPACT CURRENT_GOLF_TYPE car . setLength ( { Car ( ) ; 4199 1779 1479 ) ; ) ; ) ; ) ; ) ; Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Programmierbeispiel 7 - Kalender Zur Vertiefung des Verständnis von Container und Layouts, soll eine weitere Anwendung mit dem GridBagLayout geschrieben werden. Diese zeigt einen sauber formatierten Jahreskalender an, der die gesamte Oberäche in Anspruch nehmen sollte. Achten Sie bei dieser Übung darauf, dass Sie Hilfsklassen der Java Runtime nutzen, um z. B. eine Liste der Monate in der korrekten Sprachumgebung (Locale) zu bekommen. Objektorientierte Programmierung in Java Java, Swing und Eclipse Einführung in Grasche Benutzerobächen in Java (Fortsetzung) Programmierbeispiel 7 - Kalender (Screenshot) Objektorientierte Programmierung in Java Java, Swing und Eclipse Zusammenfassung Zusammenfassung Autovervollständigung hilft bei wiederkehrenden einfachen Tätigkeiten Tastaturabkürzungen in der IDE nutzen Styleguide und Konventionen Prinzipien des Oberächenbaus: Komponenten, Container, Layouts und Ereignisse Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Erzeugung eigener Komponenten Eigene Komponente erstellen Um eine eigene Komponente zu erstellen, muss von der Klasse JComponent abgeleitet werden. Dadurch entsteht eine Komponente mit den nötigen Basisfunktionen, die allerdings zu Beginn nichts darstellt. Um seine eigene Darstellung zu denieren muss die Methode paintComponent(Graphics g) überschrieben werden. Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Erzeugung eigener Komponenten Graphics Objekt Das Graphics Objekt bietet eine Reihe von Methoden an, um auf einer Oberäche Linien, Kreise, Rechtecke und so weiter zu zeichnen. Darüberhinaus unterstützt es verschiedene Farben, die Möglichkeit Bilder einzublenden und Text auf die Komponente zu malen. Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Erzeugung eigener Komponenten Graphics versus Graphics2D Die Klasse Graphics ist abstrakt, d. h. die eigentliche Implementierung kann je nach System und Version in unterschiedlichen Klassen stecken. In der Regel versteckt sich bei Swing Komponenten hinter dem Graphics Objekt ein Objekt vom Typ Graphics2D. Um an den erweiterten Funktionsumfang von Graphics2D zu kommen, muss das Graphics Objeckt auf Graphics2D gecasted werden. Graphics2D g2d = (Graphics2D)g; Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Erzeugung eigener Komponenten Beispiel Methode paintComponent() 1 2 3 4 5 6 7 8 9 protected void Dimension paintComponent ( G r a p h i c s d = getBounds ( ) . g e t S i z e ( ) ; g . s e t C o l o r ( C o l o r . WHITE ) ; g . f i l l R e c t (0 , 0, d . width , d . height ) ; g . s e t C o l o r ( C o l o r . BLACK ) ; g . drawLine (0 , } 0, d . width , d . height ) ; g) { Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Programmierbeispiel - Uhr Programmierbeispiel 8 - Klassische analoge Uhr Als Beispielprojekt soll die klassische analoge Uhr dienen. Auf weiÿem Hintergrund soll eine mit schwarzen Linien, Dreiecken und Kreisen gezeichnete Uhr entstehen, welche die aktuelle Uhrzeit anzeigt. Als Taktgeber soll ein java.util.Timer im Zusammenspiel mit einem java.util.TimerTask dienen. Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Programmierbeispiel - Uhr Tipps und Tricks: Timer und TimerTask 1 2 3 4 5 6 7 8 9 10 11 12 13 public class public MainClass static Timer timer void { main ( S t r i n g [ ] = new t i m e r . s c h e d u l e ( new args ) { Timer ( ) ; MyTimerTask ( ) , 1000 , 1337) ; } } public class public // } } void ... MyTimerTask run ( ) { extends TimerTask { Objektorientierte Programmierung in Java Java, Swing und Eclipse - Praktische Aufgaben Programmierbeispiel - Uhr Tipps und Tricks: Grad, Bogenmaÿ und Sinus 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static return d ∗ double Math . P I degToRad ( / double 180.0; } public // void foobar () { double degree = double radian = degToRad ( degree ) ; double result = Math . s i n ( radian ) ; // } static ... ... 90.0; d ) { Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Programmablauf Ein Computerprogramm folgt einem vorgegebenen sequentiellen Ablauf der durch die Programmierung bestimmt ist. In vielen Situationen ist es jedoch notwendig verschiedene Teile des Programm gleichzeitig auszuführen. Verschiedene Anfragen in einem Server gleichzeitig verarbeiten. Die Inhalte einer GUI während einer Berechnung aktualisieren. Tätigkeiten, wie z. B. Aufräumen in den Hintergrund verlagern. Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Lösungsstrategien Eigenbau - Eine Schleife iteriert über alle aktuellen Tätigkeiten und lässt diese dann abarbeiten. Threads - Eine standardisierte Variante innerhalb eines Prozesses verschiedene Programmabschnitte laufen zu lassen. Prozesse - Für jede Tätigkeiten einen eigenen Prozess verwenden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Vor- und Nachteile der Eigenbau Lösung Solche Eigenbau Lösungen können in vielen Programmen vorkommen. Damit lassen sich kleine Aufgaben meist leicht lösen. Dieser Ansatz ist i. d. R. immer auf ein bestimmtes Problem zugeschnitten. Es werden dabei keine Gedanken über Ablaufsicherheit oder Variablensichtbarkeiten gemacht. Parallele Tätigkeiten werden damit in jedem Fall serialisiert. Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Vor- und Nachteile der Thread Lösung Viele Programmiersprachen bieten ein Thread Konzept. Damit übernimmt eine Steuerkomponente zur Laufzeit des Programms die Koordination der nebenläugen Tätigkeiten. Jede nebenläuge Tätigkeiten - Thread genannt - kann einen Einuÿ auf die Ablaufsteuerung nehmen. Speicherinhalte des Prozesses selbst sind in allen Threads sichtbar. Die Abarbeitung erfolgt quasi-parallel. Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Vor- und Nachteile der Prozess Lösung Um Nebenläugkeit mit verschiedenen Prozessen abzubilden, wird ein Betriebssystem benötigt, dass Prozess Forking und Prozesskommunikation unterstützt. Ein Prozess kopiert sich dabei selbst und in der Kopie wird dann ein anderen Ablaufpfad eingeschlagen als im Original. Jeder Prozess hat damit seinen eigenen Speicherbereich. Je nach Prozessoren und Betriebssystem erfolgt die Abarbeitung echt-parallel oder quasi-parallel. Objektorientierte Programmierung in Java Nebenläugkeit in Java Einführung in die Problematik Probleme der Paralellität Arbeiten mehrere Tätigkeiten parallel kann dies zu verschiedenen Laufzeitproblemen führen: Lost-Update Dirty-Read Deadlock ... Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Problem - Lost Update / Write-Write Conict Bezeichet das Problem, wenn mindestens zwei konkurrierende Tätigkeiten auf einen Datensatz schreiben wollen und sich dabei überschneiden. Wenn die beiden Transaktionen abwechselnd ihre Arbeitsschritte durchführen, so überschreibt die zweite Transaktion das Ergebnis der Ersten. Das erste Ergebnis geht verloren. Dies kann mit Hilfe eines kritischen Abschnitts gelöst werden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Problem - Dirty-Read / Write-Read Conict Ein Dirty-Read kann dann auftreten, wenn zwei Teilaktionen gleichzeitig auf einen Datensatz lesend zugreifen, obwohl eine der beiden Teilaktionen noch nicht abgeschlossen ist, d. h. die Daten z. B. noch nicht nal feststehen. Die andere Teilaktion arbeitet dann mit möglicherweise falschen Daten. Abhilfe schat die Denition eines kritischen Abschnitts. Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Begri - Kritischer Abschnitt Mit einem kritischen Abschnitt wird eine Folge von Anweisungen im Programm bezeichnet, die nicht unterbrochen werden kann ohne das dadurch Inkonsistenzen im Datenbestand entstehen oder falsche Ergebnisse erzeugt werden. Der Begri kann sich auf einige einzelne Anweisungen beziehen, auf Anweisungen im Umfeld eines Objekts oder auf ganze Methoden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Begri - Race Condition Mit Race Condition wird in der Praxis oft ein Zustand beschrieben, bei dem das Ergebnis einer Anwendung oder Funktion von Laufzeitverhalten der Anwendung abhängt. In elektronischen Schaltkreisen werden solche Race Conditions auch als Glitch bezeichnet. Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Begri - Deadlock Ein Deadlock bezeichnet den Zustand bei dem verschiedene Threads auf Ressourcen warten die jeweils vom einem anderen Thread blockiert werden. Ein einfaches Beispiel: Thread A wartet auf Ressource X, die aber von Thread B gehalten wird. Thread B wartet jedoch auf Ressource Y, die von A gehalten wird. Diese Verklemmung kann nicht aufgelöst werden und führt daher zum Stillstand beider Threads. Objektorientierte Programmierung in Java Nebenläugkeit in Java Begrie und Probleme bei Nebenläugkeit in Java Begri - Hung Thread Als Hung Thread bzw. hängende/stillstehende Threads werden in Java Threads bezeichnet die aus verschiedenen Gründen nicht mehr weiter arbeiten. Mögliche Ursachen sind z. B. ein Deadlock, Programmierfehler, Endlosschleifen oder wirklich sehr langlaufende Threads. In Java gibt es keine Möglichkeit einen hängenden Thread sauber zu beenden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Threads als Nebenläugkeitskonzept Da Java Anwendungen in einer Virtuellen Maschine laufen und diese virtuelle Maschine als Prozess im Betriebssystem, scheidet eine prozess-basierte Lösung in Java aus. Java bietet allerdings per Spezikation ein thread-basiertes Nebenläugkeitskonzept an. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Threads erzeugen Es gibt zwei Varianten, um in Java Nebenläugkeit mit Threads zu ermöglichen: Eigene Klasse von Klasse java.lang.Thread ableiten und run() Methode überschreiben. Eigene Klasse vom Interface java.lang.Runnable ableiten und run() Methode implementieren. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Eigenen Thread denieren 1 2 3 4 5 6 7 8 9 public // class ... public // } } ServiceThread void ... run ( ) { extends Thread { Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Eigenen Thread nutzen 1 2 3 4 5 6 public void foobar () ServiceThread thread = new ServiceThread ( thread . s t a r t () ; } { thread ; 42 , " wombat " ) ; Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Eigenes Runnable denieren 1 2 3 4 5 6 7 8 9 public // class ... public // } } ServiceRunnable void ... run ( ) { implements Runnable { Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Eigenes Runnable nutzen 1 2 3 4 5 6 7 8 9 public void Thread Runnable runnable thread foobar () runnable ; = new = new ServiceRunnable ( Thread ( thread . s t a r t () ; } { thread ; runnable ) ; 42 , " wombat " ) ; Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Lebenszeit Ein neu erzeugter Thread startet nicht automatisch. Mit der Methode start() beginnt der Thread und kann dann von auÿen nicht explizit zum Anhalten gebracht werden. Die Methoden stop(), resume(), suspend() und dispose() sind zwar aus Kompatibilitätsgründen vorhanden, dürfen allerdings nicht mehr verwendet werden. Ein Thread endet, wenn er das Ende der run() Methode erreicht. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Status NEW - Ein neu erstellter Thread, der noch nicht gestartet wurde. RUNNABLE - Thread der im Moment von der Virtual Machine ausgeführt wird. BLOCKED - Thread der auf einen Monitor Lock wartet. WAITING - Thread der auf unbestimmte Zeit auf die Aktionen von anderen Threads wartet. TIMED_WAITING - Thread der eine bestimmte Zeit auf die Aktionen von anderen Threads waret. TERMINATED - Thread der das Ende seines Lebenszyklus erreicht hat. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Steuerung Der Thread selbst kann seinen aktuellen Ablauf unterbrechen, wenn z. B. im Moment keine Arbeit ansteht. Dies kann auf eine feste Zeit xiert werden indem die Methode sleep() aufgerufen wird oder der Virtual Machine überlassen werden wenn yield() genutzt wird. Ein Thread kann seinen Ablauf auch abhängig von Ressourcen machen. Dafür ruft der Thread die wait() Methode der gewünschten Ressource auf und wird damit solange schlafen gelegt bis ein notify() oder ein notifyAll() dieser Ressource gerufen wird. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Steuerung - Allgemein In Anwendungsfällen bei dennen unterschiedliche Threads auf jeweils unterschiedlichen Daten arbeiten, beschränkt sich die Thread Steuerung auf das Starten des Threads und dem anschlieÿenden zusammenführen aller gestarteten Threads. Ein anderer Thread kann mit dem aktuellen Thread mittels join() wieder zusammengeführt werden. Dafür müssen allerdings Referenzen zu allen erstellten Threads vorhanden sein. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Steuerung - Monitore (Mutex) Thread Steuerung wird komplizierter, wenn auf gemeinsame Datenquellen lesend und schreibend zugegrien wird. Dabei müssen Maÿnahmen getroen werden, um einen geregelten Zugri zu ermöglichen. Dafür biete Java die Möglichkeit Objekt Sperren ähnlich zu Datenbanken zu nutzen: Diese Sperren werden Monitore genannte. Gelegentlich kann auch der Name Mutex vorkommen. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Steuerung - Schlüsselwort synchronized Mit Hilfe des Schlüsselwortes synchronized können kritische Abschnitte gekennzeichnet werden. Es kann an folgenden Stellen verwendet werden: Block - Mit synchronized( Monitor ) wird ein Monitor angefordert und der danach folgende Block wird im exklusiven Zugri auf dieses Objekt ausgeführt. Methode - Eine Methode kann mit Hilfe der Modizieres synchronized markiert werden. Diese Methode darf dann nur noch von einem Thread gleichzeitig durchlaufen werden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Thread Steuerung - Anmerkungen zu synchronized Generell sollte das Schlüsselwort synchronized für Methoden nur sparsam eingesetzt werden, da es die Ausführungsgeschwindigkeit reduziert und Deadlock Situationen begünstigt. Ein synchronized Block dagegen kann speziell auf die kritische Variable ausgerichtet und auch im Umfang begrenzt werden. Es gilt: Kritische Pfade so kurz wie möglich halten, um die Ausführungsgeschwindigkeit nicht zu reduzieren und Deadlocks zu vermeiden. Objektorientierte Programmierung in Java Nebenläugkeit in Java Nebenläugkeit in Java Threadsonderform Daemon Ein Thread kann bevor er zur Ausführung freigegeben wird als Daemon Thread markiert werden. Solche Daemon Threads sollten nur für Hintergrundaktivitäten genutzt werden, da diese von der Java Virtual Machine gesondert behandelt werden. Threads die nicht als Daemon gekennzeichnet sind, werden User Threads genannt. Damit die Virtual Machine eine Anwendung ordentlich beenden kann, müssen alle User Threads korrekt terminieren. Objektorientierte Programmierung in Java Nebenläugkeit in Java Programmierbeispiele Nebenläugkeit Programmierbeispiel 9 - Deutsche Bahn Uhr Auf Basis des DBClock Projekts soll eine Bahnhofsuhr der Deutschen Bahn implementiert werden. Diese funktioniert nach den folgenden Regeln: Alle 60s zur vollen Minute stöÿt ein zentraler Taktgeber die internen Taktgeber aller Uhren an. Diese laufen dann unabhängig vom Zentraltakt mit ihrem eigenen Takt und Umrunden das komplette Ziernblatt mit dem Sekundenzeiger in etwa 58s. Danach wird wieder auf den Zentraltakt gewartet. Dadurch scheint es als würde die Uhr 2s auf der vollen Minute stehen bleiben. Objektorientierte Programmierung in Java Nebenläugkeit in Java Zusammenfassung Zusammenfassung Strategien für Nebenläugkeit Problem bei nebenläugen Anwendungen Nebenläugkeit in Java (Thread und Runnable) Thread Eigenschaften Thread Steuerung Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Wozu Generics? In der objektorientierten Programmierung gibt es sich oft wiederholende strukturelle Muster, welche auf eine Vielzahl von Objekt Typen anwendbar sind. Ein typischer Vertretung dieser Muster sind z. B. Listen oder andere Kollektionen von Objekten. Generics helfen ähnlich geartete Problemstellung zu beschreiben, Codeduplikation zu vermeiden und den Quelltext dadurch wiederverwendbarer zu machen. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Generics in Java Generics wurden mit Java 5 (bzw. 1.5) in die Sprach Sepzikation eingeführt. Bis dahin gab es kein Konzept für generische Programmierung in Java selbst. Die bis dahin verwendete Syntax ist weiterhin gültig, wird allerdings ja nach Verwendung mit Compiler Warnungen markiert. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Das Listen Problem Java unterstützt die Entwicklung von Software durch eine groÿe Anzahl an bereits implementierten Grundlagentechnologien, wie z. B. dynamische Listen, assoziative Speicher, Netzwerktechnologien oder Sortieralgorithmen. Bis Java 5 hatten allerdings die eingebauten Listen (z. B. LinkedList ) das Problem nicht typspezisch zu sein: Sie akzeptierten alle Objekte vom Typ Object. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Das Listen Problem - ohne Generics In der Anwendung muss daher darauf geachtet werden, welche Typen in die Liste gesteckt werden. Beim Zugri auf Elemente der Liste musste dann per Cast wieder auf den erwarteten Typ gewechselt werden. Dabei kann es sehr schnell zu Cast Exceptions kommen, wenn Objekten Typen gemischt werden. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Das Listen Problem - ohne Generics (Code) 1 2 3 4 5 6 7 8 9 10 11 private List static foobar () { = new LinkedList () ; l i s t . add ( "1 s t " ) ; l i s t . add ( " 2 nd " ) ; l i s t . add ( "3 rd " ) ; l i s t . add ( "4 th " ) ; // ... l i s t . add ( } void list new I n t e g e r (42) ) ; Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Das Listen Problem - mit Generics Mit Hilfe von Generics kann der Listen Klasse einen zusätzlicher Parameter mitgeteilt werden, der den zu verwendenen Objekt Typ deniert. Dazu können verschiedene Varianten gewählt werden: Nennung einer Klasse (z. B.: List<String> list) Angabe eines Interfaces (z. B.: List<Serializable> list) Nutzung eines generischen Parameters (z. B.: List<T> list) Wildcard (z. B.: List<?> list) Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Das Listen Problem - mit Generics (Code) 1 2 3 4 5 6 7 8 9 10 private static L i s t <Number> } void list foobarNumbers ( ) = new l i s t . add ( ( byte ) 1 l i s t . add ( ( short ) 2 ) ; ) ; l i s t . add ( 3 ) ; l i s t . add ( 4L ) ; l i s t . add ( 5f ) ; l i s t . add ( 6. ) ; { L i n k e d L i s t <Number >() ; Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Typsichere Liste mit Generics Damit lässt sich z. B. eine typsichere Liste von String Objekten denieren. Der Versuch ein Objekt von einem anderen Typ hinzuzufügen, führt unweigerlich zu einem Fehler zur Compilezeit. Zusätzliche Abfragen zur Laufzeit sind damit überüssig. List<String> stringList = new LinkedList<String>(); Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Erweiterung der Java Syntax für Generics Mit dem Einzug von Generics in Java musste die bis dahin gültige Syntax erweitert werden. Dies umfasst zwei Teilgebiete: Nutzung von Generics Denition von generischen Klassen/Interfaces Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Nutzung von Generics - direkte Parameter Generische Klassen erwarten einen Parameter, der den generischen Typ deniert. Dieser Parameter muss in spitzen Klammern nach dem Klassennamen angegeben werden. Benötigt die generische Klasse mehr als einen Parameter, dann werden diese durch Komma getrennt innerhalb der spitzen Klammern aufgelistet. List<String> list Map<Integer, String> map Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Nutzung von Generics - Wildcards Mit Wildcards können Familien von Objekttypen zugelassen werden. Dafür existieren drei Varianten: <? extends X> - Upper Type Bound X und alle abgeleiteten Klassen von X <?> - Unbound Alle Klassen (universal Wildcard) <? super X> - Lower Type Bound X und alle Superklassen von X Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Denition von Generics - Klassenebene Soll eine generische Klasse geschrieben werden, dann muss dies durch Nennung der generischen Parameter in der Klassen oder Interface Denition erfolgen. 1 2 3 4 5 6 7 8 9 10 public class public // void M y S t o r e<Main , Sub> { acceptMainItem ( Main entry ) ... } public // } } void ... acceptSubItem ( Sub entry ) { { Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Denition von Generics - Methodenebene Wird nur in einigen Methoden einer Klasse ein generischer Parameter benötigt, dann kann dieser dem Rückgabewert der Methode vorangestellt werden. 1 2 3 public // } <T> ... void doSomethingElse ( T entry ) { Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Einführung in Generics Denition von Generics - Generische Parameter verfeinern Die verwendeten generischen Parameter in Klassen, Interfaces und Methodendenitionen können zudem noch erweitert werden, um den zu verwendenen Objekttyp genauer zu spezizieren. Mit z. B. T extends Z wird speziziert das der Parameter T von der Klasse Z abgeleitet sein muss. Diese Syntax gilt auch für Interfaces. Mehrere Interface werden mit & getrennt angegeben. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Programmierbeispiel Generics Programmierbeispiel 10 - Einfach verkettete Liste Im ersten Beispiel soll eine einfach verkette Liste mit Hilfe von Generics erstellt werden, die beliebige Typen aufnehmen kann. Jedes Element der Liste kennt nur seinen nächsten Nachbarn. Es sollen keine in Java eingebauten Listentypen verwendet werden. Für ein Listenelement kann natürlich eine zusätzliche Klasse verwendet werden. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Programmierbeispiel Generics Programmierbeispiel 11 - Cache Im zweiten Beispiel soll ein spezieller Cache erstellt werden. Dieser Cache hat eine denierte maximale Gröÿe und auch seine Elemente dürfen eine gewissen Zeichenlänge nicht überschreiten. Im Cache sollen unter beliebigen Schlüsseltypen Character Sequenzen (Strings) abgelegt werden. Wird die maximale Cachegröÿe überschritten, so darf ein altes Element gelöscht werden. Objektorientierte Programmierung in Java Generics / Generische Programmierung in Java Zusammenfassung Zusammenfassung Generische Klassen nutzen Generische Klassen schreiben Nutzung von Wildcards Nutzung des Schlüsselwortes extends bei Generics Objektorientierte Programmierung in Java Java Vertiefung Begrisdenition Bean Begrisdenition Bean Bean oder Java Bean werden Java Klassen genannt, die andere zusammengehörige Objekte in einer Klasse gekapselt zusammenfassen und den folgenden Konventionen genügen: Konstruktor ohne Argumente serialisierbar Getter/Setter-Methoden Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Design Patterns Als Design Pattern (deutsch: Entwurfsmuster) werden programmatische Konstrukte bezeichnet, welche übliche Aufgabenstellung der Software Entwicklung elegant, performant, universell und/oder hochgradig-wiederverwendbar lösen. Der Begri wurde hauptsächlich durch das Buch Design Patterns Element of Reusable Object-Oriented Software von Gamma, Helm, Johnsen und Vlissides geprägt. Diese Vierergruppe wird oft auch als die Gang of Four (GoF) bezeichnet. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Design Patterns - Einteilung Die Gang of Four stellte in ihrem Buch 23 Design Patterns vor. Es gibt allerdings eine Reihe von weiteren Patterns und auch Anti-Patterns. Typischerweise werden diese Pattern in Kategorien eingeteilt: Erzeugende Muster Strukturelle Muster Verhaltensmuster Sonstige Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Factory Method-Pattern Die Idee des Factory Method-Pattern ist die Objektgenerierung durch eine Methode statt dem direkten Aufruf des Konstruktors. Damit lassen sich wiederkehrende Objektgenerierungen verallgemeinern und Code Duplikation vermeiden. Je nach Sprachgebrauch verstecken sich hinter dem Factory Method-Pattern verschiedene unterschiedliche Design Patterns. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Non-GoF Factory Method-Pattern In der Praxis weitverbreitet ist die einfachste Form des Factory Method-Patterns, bei dem eine statische Methode ein Objekt eines speziellen Typs baut und als Ergebnis zurückliefert. Vererbung und Polymorphismus kommen dabei nicht zur Anwendung. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Non-GoF Factory Method-Pattern - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 public static final Car Car car buildBaseGolf () = new car . setManufacturer ( "VW" car . setModel ( ) ; " Golf " car . setClassName ( car . setType ( car . setWidth ( car . setHeight ( return } car ; ) ; C a r . CLASS_COMPACT CURRENT_GOLF_TYPE car . setLength ( { Car ( ) ; 4199 1779 1479 ) ; ) ; ) ; ) ; ) ; Objektorientierte Programmierung in Java Java Vertiefung Design Patterns MVC-Pattern Beim Model-View-Control (MVC) Pattern werden die fraglichen Programmteile so in verschiedene Abschnitte zerlegt, dass sich eine saubere Aufteilung nach Inhalt, Steuerung und Darstellung erzeugt. Model - Kapselt den eigentlich Inhalt (Content) View - Übernimmt die Aufgabe der Darstellung Controller - Steuerung und Logik für die Daten im Model Objektorientierte Programmierung in Java Java Vertiefung Design Patterns MVC-Pattern - Beispiel 1 2 3 4 5 6 7 8 9 [ . . . ] DataModel GUI v i e w = new Controller [ . . . ] mo d el = D a t a B a s e A c c e s s . readModelFromDB ( ) ; GUI ( ) ; controller = new I O C o n t r o l l e r ( model , view ) ; Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Template-Pattern Eine abstrakte Klasse wird als Vorlage (Template) genutzt indem man die grundlegende Funktionalität ausimplementiert, allerdings einzelne Programm Bausteine als abstrake Methoden deniert. Dadurch zwingt die Vorlagenklasse einen Implementierer die notwendigen Einzelaktionen für einen spezischen Fall zu codieren, der grundlegende Ablauf bleibt aber in Kontrolle des Vorlagenschreibers. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Template-Pattern - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 public abstract class LifeCycleComponent abstract void i n i t i a l i z e () ; abstract void startComponent () ; abstract void endComponent ( ) ; public final void runLifeCycle { i n i t i a l i z e () ; startComponent () ; endComponent ( ) ; } } { Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Reset-Pattern In Situationen mit sehr vielen (Hilfs-)Objekt Erstellungen, kann es hilfreich sein mit Hilfe des Reset-Patterns ständig wiederkehrende Objekt Erstellungen zu vermeiden. Statt ein Objekt dem Garbage Collector zu überlassen und ein neues zu erstellen, wird ein bestehendes Objekt recycled. Dafür wird eine Methode reset erstellt, welche ähnlich wie ein Konstruktor einen denierten Zustand wieder herstellt. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Reset-Pattern - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class SomeClass { private Object field0 ; private Object field1 ; public // SomeClass ( Object initial field0 , Object field1 ) { reset reset ( field0 , field1 ) ; } public } } void r e s e t ( Object this . field0 = field0 ; this . field1 = field1 ; field0 , Object field1 ) { Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Singleton-Pattern Das Singleton Pattern wird angewendet, um die Anzahl an Instanzen einer bestimmten Klasse zu reglementieren. In den meisten Fällen soll z. B. nur eine einzelne Instanz einer Klasse zugelassen werden. Dafür wird der Zugri auf den Kontruktor gesperrt und Zugang zur Klasse mit einer zusätzlichen statischen Methode/Funktion hergestellt. Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Singleton-Pattern Eager - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class private IOComponent final static { IOComponent instance IOComponent ( ) ; private IOComponent ( ) { [ . . . ] } public static return } [ . . . ] } IOComponent instance ; getInstance () { = new Objektorientierte Programmierung in Java Java Vertiefung Design Patterns Singleton-Pattern Lazy - Beispiel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class IOComponent private static private IOComponent ( ) { { IOComponent instance = null ; [ . . . ] } public if ( static instance return } [ . . . ] } IOComponent instance == = new instance ; null getInstance () ) IOComponent ( ) ; { Objektorientierte Programmierung in Java Java Vertiefung Programmieraufgabe - GUI & Objekte (Fortsetzung) Programmierbeispiel 12 - Füllstandsanzeige Schreiben Sie eine Klasse, welche eine Art Lager beschreibt in welchem sich Gegenstände benden. Ein Objekt dieser Klasse erlaubt das Auslesen und Setzen des aktuellen Füllstands allerdings immer mit absoluten Werten. Schreiben Sie weiterhin einen Thread welcher den akutellen Füllstand ausliest und mit einem Delta (z. B. -5) verrechnet. Das Ergebnis setzt der Thread dann wieder am Lager Objekt. Fügen Sie weitere Threads hinzu, welche mit weiteren Deltas (z. B. +10, -3) arbeiten. Welches Verhalten kann beobachtet werden?