287
Prof. Dr.-Ing. Holger Vogelsang holger.vogelsang@hs- karlsruhe.de Informatik 2 Einführung in Java und UML

Informatik 2 Einführung in Java und UML

  • Upload
    eve

  • View
    79

  • Download
    3

Embed Size (px)

DESCRIPTION

Informatik 2 Einführung in Java und UML. Prof. Dr.-Ing. Holger Vogelsang [email protected]. Inhaltsverzeichnis. Roter Faden (4) Übersicht (6) Übersicht: (12) Übersicht (13) Arbeitsschritte und Software (17) Imperative Aspekte (37) Klassen und Objekte (50) - PowerPoint PPT Presentation

Citation preview

Page 1: Informatik 2 Einführung in Java und UML

Prof. Dr.-Ing. Holger Vogelsang [email protected]

Informatik 2Einführung in Java und UML

Page 2: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 2

Inhaltsverzeichnis

Roter Faden (4) Übersicht (6) Übersicht: (12) Übersicht (13) Arbeitsschritte und Software (17) Klassen und Objekte (37) Fehlererkennung (90) Zusicherungen (97) Klassen und Objekte (109) Überladen von Methoden (119) Vererbung (124) Überschreiben von Methoden (156) Vererbung (183) Generische Klassen (193) Generische Methoden (206)

Page 3: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 3

Inhaltsverzeichnis

Generische Klassen (206) Aufzähltypen (210) Regeln und Hinweise (216) Klassendiagramme (228) Fehlerbehandlung mit Ausnahmen (260) Funktionale Programmierung (276)

Page 4: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 4

Roter Faden

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 5: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 5

Roter Faden

GrafischeOberflä-

chenÜbersicht Layouts Widgets Zeichen-

operationenGrafik-

widgetsEffekte,

AnimationenOffenePunkteEreignisse

Daten-strukturen ADTs Elementare

DatenstrukturenHash-

tabellen Bäume GraphenIteratorenDatenstrukturenin Java

Typinfo.,I/O

Annota-tionen

Laufzeit-typinfo.

Ein-,Ausgabe

JavaScript Prinzipien Einstieg VererbungObjekte DOM-ZugriffeModule

Page 6: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 6

Übersicht Literatur

Java Christian Ullenboom:

„Java ist auch eine Insel“, Rheinwerk Verlag GmbH (auch frei als „Open-Book“ unter http://openbook.rheinwerk-verlag.de/javainsel/)

„Java 8 – Mehr als eine Insel“, Rheinwerk Verlag GmbH D. Ratz, J. Scheffler, D. Seese, J. Wiesenberger: „Grundkurs Programmieren in Java“, Hanser-

Verlag R. C. Martin: „Clean Code“, mitp Cay S. Hortsmann, „Java 8 SE for the Really Impatient“, Addison-WesleyObjektorientierung allgemein B. Lahres, G. Raýman: „Objektorientierte Programmierung“, Rheinwerk Verlag GmbH (auch

frei als „Open-Book“ unter http://openbook.rheinwerk-verlag.de/oop/)Konfigurationsmanagement und Build-Systeme G. Popp: „Konfigurationsmanagement mit Subversion, Maven und Redmine“, dpunkt

Page 7: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 7

Übersicht Literatur

UML (Objekt- und Klassendiagramme) M. Jeckle, C. Rupp, J. Hahn, B. Zengler, S. Queins: „UML 2 - glasklar“, Hanser-Verlag C. Kecher: „UML 2.5 – Das umfassende Handbuch“, Rheinwerk Verlag GmbHJavaFX C. Dea: „JavaFX 2.0: Introduction by Example“, Apress A. Epple, „Workshop JavaFX 8“, dpunkt.verlag GmbH D. Kupfer, C. Ebert: „JavaFX-Kompendium“, entwickler.press (Mai 2015) http://docs.oracle.com/javase/8/javase-clienttechnologies.htmDatenstrukturen G. Saake, K. Sattler: „Datenstrukturen und Algorithmen: Eine Einführung mit Java“, dpunktJavaScript O. Zeigermann: „JavaScript für JavaEntwickler“, entwickler.press D. Flanagan: „JavaScript – kurz & gut“, O‘Reilly M. Haverbeke: „Eloquent JavaScript“, kostenlos unter http://eloquentjavascript.net/ JavaScript-Referenz: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference

Page 8: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 8

Übersicht Entwicklungsumgebungen

IDEs zur Java-Entwicklung Eclipse: http://www.eclipse.org mit zusätzlichen Plugins:

Findbugs: In Eclipse Help Eclipse Marketplace, „Findbugs“ im Suchfeld eingeben und „Findbugs Eclipse Plugin” installieren

Checkstyle zur Überprüfung der Code-Konventionen: In Eclipse Help Eclipse Marketplace, „Checkstyle“ im Suchfeld eingeben und „Checkstyle Plug-in” installieren

SVN Team Provider: In Eclipse Help Eclipse Marketplace, SVN im Suchfeld eingeben und Subversive SVN Team Provider installieren

SVN Connector: In Eclipse Help Install New Software Add… SVN-Connector mit der Update Site http://community.polarion.com/projects/subversive/download/eclipse/3.0/kepler-site/ eingeben OK Im Baum links die neueste Version der SVNKit Implementation sowie des SVN Connectors auswählen und installieren.

Page 9: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 9

Übersicht Entwicklungsumgebungen

Netbeans: http://www.netbeans.org IntelliJIDEA

freie Community-Version: http://www.jetbrains.com/idea/ oder Ultimate Edition mit Lizenz der Hochschule:

https://ilias.hs-karlsruhe.de/goto.php?target=crs_99205&client_id=HSKA (Kursbeitritt erforderlich)

IDEs zur JavaScript-Entwicklung Eclipse: http://www.eclipse.org mit WTP-Plug-ins WebStorm: http://www.jetbrains.com/webstorm/ (Lizenz-Information im Ilias) Ausprobieren kleinerer Code-Stücke: http://jsfiddle.net/

Page 10: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 10

Übersicht Modellierungswerkzeuge

Leicht verfügbare Modellierungswerkzeuge Visual Paradigm for UML

Frei verfügbare Community-Edition Lizenz für die Professional-Edition im Ilias:

https://ilias.hs-karlsruhe.de/goto.php?target=crs_32415&client_id=HSKA Download http://www.visual-paradigm.com/ keine Code-Erzeugung in der Community-Edition

Magicdraw Frei verfügbare Community-Edition http://www.magicdraw.com/ Code-Erzeugung für C++, C# und Java (nicht Community-Edition)

Borland Together http://www.borland.com/us/products/together/index.html Lizenz bei Frau Knodel in LI 136

Page 11: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 11

Übersicht Modellierungswerkzeuge

UML Lab Kostenlose Studentenlizenz unter http://www.uml-lab.com/de/uml-lab/academic/

Page 12: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 12

Übersicht: Änderungen zum Wintersemester 2015/2016 und Arbeitsaufwand

Änderungen keine

Arbeitsaufwand Vorlesung: 4 ECTS-Punkte, 4 SWS ergeben 120 Stunden Aufwand (60 Stunden Präsenz, 60 Stunden

eigenständige Arbeit)Arbeitsaufwand Übung: 3 ECTS-Punkte, 2 SWS ergeben 90 Stunden Aufwand (30 Stunden Präsenz, 60 Stunden

eigenständige Arbeit)

Page 13: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 13

Übersicht Hinweise

Markierungen Expertenkapitel (nicht klausurrelevant):

Tafel-/ Rechnerübungen: Längeres Beispiel:

Pacman-Beispiel:

Page 14: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 14

Übersicht Historie im Informatikstudium

Bekannt sind aus „Informatik 1“: Datentypen Prozedurale Elemente einfache Klassen, Objekte Arrays Algorithmen zum Suchen und Sortieren Klassen in UML

Page 15: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 15

Übersicht Durchgängiges Beispiel: Pacman-Klon

Java und die Datenstrukturen werden anhand eines kleinen Spielfragmentes erläutert, einer Variation von Pacman:

nur einen Level verändertes Spielfeld andere Punktezählung veränderter interner Aufbau, um alle wichtigen Techniken zeigen zu können fehlende Spielelemente des Originals teilweises anderes Verhalten der Figuren Vektor- statt Pixelgrafik plattformunabhängige Implementierung mit JavaFX

Page 16: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 16

Übersicht Durchgängiges Beispiel: Pacman-Klon

Spielfeld:

Spielende: Pacman wurde von einem Geist gefressen, oder alle Essensrationen sind von Pacman gefressen worden.

Geist

Pacman

Essen

Kirsche (Geister werden für eine gewisseZeit ungefährlich und können gefressenwerden)

Tor zur anderen Seite

Page 17: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 17

Arbeitsschritte und Software Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 18: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 18

Arbeitsschritte und Software Motivation

Bekannt aus Informatik 1: Schreiben einfacher Java-Programme Wie kann der Quelltext verwaltet werden?

Page 19: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 19

Arbeitsschritte und Software Ausführbares Programm

Erzeugen eines ausführbaren Programmes

QuellcodePacman.java

QuellcodeCherry.java

QuellcodeGhost.java

BytecodePacman.class

CompilerArchiv

(Pacman.jar)

jarCompiler

CompilerBytecode

Ghost.class

BytecodeCherry.class

Manifest.mf

Bilder/…

Manifest-Version: 1.0Main-Class: de.Main

Page 20: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 20

Arbeitsschritte und Software Versionsverwaltung

Warum sollen die Quelltexte nicht nur im Dateisystem des Entwicklers liegen? Gruppenarbeit:

- Viele Entwickler arbeiten an einem Programm Zugriff auf deren Quelltexte.- Was haben die anderen Entwickler gemacht oder geändert?- Was habe ich an dem aktuellen Projekt geschrieben?

Verbesserung der eigenen Arbeitsmöglichkeiten:- Automatisierte Sicherung: Was passiert bei Zerstörung der lokalen Daten?- Wiederherstellung eines alten Standes, wenn der neue „kaputtprogrammiert“ wurde „Undo“ zu einer bekannten Version

Wieso sollen mehrere Versionen eines Programmes gepflegt werden?- Anpassungen für Kunden- Arbeit an alter Version (Korrekturen) und neuer Version (Erweiterungen)- Vergleich unterschiedlicher Versionen was hat sich geändert?

Jede neue Version einer Datei erhält eine Versionsnummer. Ziel: Speicherung in einem zentralen „Repository“.

Page 21: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 21

Arbeitsschritte und Software Versionsverwaltung

Einflüsse während der Programmentwicklung:

Projekt

viele Entwickler

viele Versionen viele unterschiedlicheArbeitsplätze

viele Klassen undDokumente

Page 22: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 22

Arbeitsschritte und Software Versionsverwaltung

Grafischer Versionsvergleich:

Page 23: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 23

Arbeitsschritte und Software Versionsverwaltung

Lösung: Unterstützung der Entwicklung durch eine Versionsverwaltung. Auswahl: RCS/CVS: veraltet SVN: sehr häufig im Einsatz, ein zentraler Server Git: manchmal als Nachfolger von SVN gesehen, verteilte Datenhaltung auf mehreren

Servern, oft in Open-Source-Projekten, in Firmen noch selten anzutreffen Team Foundation Version Control: reine Microsoft-Lösung

In Informatik 2 und im Softwarelabor: Arbeit mit Subversion (SVN) Genauere Einführung z.B. unter http://svnbook.red-bean.com/

Page 24: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 24

Arbeitsschritte und Software Versionsverwaltung

Interne Speicherung im Repository: Es wird normalerweise nicht jede Version komplett abgelegt. Statt dessen speichert ein Repository die Unterschiede („Deltas“). Subversion kennt beide Varianten + komplette Speicherung nach Bedarf.

Rückwärtsdelta:schnelleres Auslesen

Version 5(aktuell)

als vollständigeDatei

Vorwärtsdelta:schnelleres Schreiben

Version 4Version 3

Version 2

Version 1 Version 1(alt)

als vollständigeDatei

Version 2

Version 3

Version 4Version 5

Deltas

Page 25: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 25

Arbeitsschritte und Software Versionsverwaltung

Wichtigste Aktionen für die Arbeit mit Subversion: Share: einmalig Projekt im Repository anlegen, eventuell lokales Projekt übergeben Check out (einmalig für ein Projekt): Projekt aus dem Repository in ein lokales

Verzeichnis kopieren Commit: lokal erzeugte Änderungen im Repository ablegen Update: zwischenzeitliche Änderungen im Repository in das lokale Verzeichnis

übernehmen Für alle Schritte gibt es Kommandozeilenwerkzeuge sollen hier nicht betrachtet werden. Die wichtigsten lassen sich auch mit IDE-Plugins durchführen.

Page 26: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 – Versionsverwaltung mit SVN 26

Arbeitsschritte und Software Versionsverwaltung (Installation in Eclipse)

Arbeit mit SVN Jetzt kann mit Window Open Perspective SVN Repository Exploring die

Ansicht aller SVN-Server angezeigt werden (ist leer). Im rechten Fenster SVN Repositories lässt sich durch Rechtsklick mit New

Repository Location ein neuer Server einrichten. Für den an der Hochschule müssen Sie folgendes eintragen:

URL: http://www.iwi.hs-karlsruhe.de/I/svn/<user>/ <user>: Ihr IZ-Benutzername Als Nutzernamen und Password geben Sie Ihren IZ-Account ein. Save authentication ist auf eigenen Rechnern ganz praktisch, damit Sie sich nicht

immer neu anmelden müssen.

Page 27: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 27

Arbeitsschritte und Software Versionsverwaltung (Projekt anlegen)

Projekt anlegen Wenn das Projekt bisher nur lokal existiert, muss es im Repository angelegt werden. Dann können alle anderen Entwickler mit der entsprechenden Berechtigung darauf zugreifen.

ProjektXYZ

Repository auf dem Server mit dem neuen Projekt

ProjektXYZ

share

http://www.iwi.hs-karlsruhe.de/I/svn/<user>/ProjektXYZ/trunk

Projekt auf demlokalen Arbeitsplatz-PC

Repository Root Projekt-Pfad

Page 28: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 28

Arbeitsschritte und Software Versionsverwaltung (Projekt anlegen)

Ablauf in Eclipse: Rechtsklick auf das Projekt Dann Team und Share Project auswählen. SVN und im nächsten Dialog Ort des Repositorys auswählen, Simple Mode ist für uns

ausreichend Kommentar eingeben und auf Finish klicken

Empfohlener Aufbau eines Projektarchivs (Repository) auf dem Server: /Projektname/trunk: Hauptentwicklungslinie des Projektes /Projektname/branches: Alternative Entwicklungen wie z.B. spezielle

Anpassungen für einen Kunden, Wechsel auf neue Technologie, … /Projektname/tags: Kopie der Hauptentwicklungslinie oder einer Verzweigung zu

einem bestimmten Zeitpunkt.- Wird z.B. angelegt, wenn eine neue Version an den Kunden ausgeliefert wird. Dann

kann ein Tag mit dem Namen der Version erzeugt wird („Version 1.0“).- Ein Tag hat keine bestimmte Bedeutung. Er erlaubt aber, bestimmte Versionen mit

einem leicht erkennbaren Namen zu versehen.

Page 29: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 29

Arbeitsschritte und Software Versionsverwaltung (Check out)

Checkout: Daten aus dem Repository auf den lokalen PC kopieren (einmalig)

Entwicklerlokale Kopie

des Quelltextes

Repository auf dem Server mit allen Versionen

des Quelltextes +zusätzlichen Binärdateien

Check out

Page 30: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 30

Arbeitsschritte und Software Versionsverwaltung (Check out)

Ablauf in Eclipse: Wechsel in die Ansicht SVN Repository Exploring Rechtsklick auf die gewünschte Version des Projektes Check Out wählen Arbeit auf der lokalen Kopie des Projektes

Page 31: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 31

Arbeitsschritte und Software Versionsverwaltung (Commit)

Commit: Lokale Änderungen in das Repository übertragen

Entwicklerlokale Kopie

des Quelltextes

Repository auf dem Server mit allen Versionen

des Quelltextes +zusätzlichen Binärdateien

Änderungeneintragen,

Konflikte lösen

Page 32: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 32

Arbeitsschritte und Software Versionsverwaltung (Commit)

Ablauf in Eclipse: Nach den lokalen Änderungen übertragen die Entwickler die neuen Daten in das

Repository. Rechtsklick auf das Projekt (z.B. in der Java-Ansicht) oder Rechtsklick auf einzelne

Pakete/Klassen Dann Team und Commit auswählen. Die Änderungen sollten unbedingt mit einem Kommentar versehen werden. Der

Kommentar beschreibt, was an der Datei geändert wurde („Fehler xyz behoben“, …). Nur geänderte Daten werden geschrieben. Sie erhalten dabei eine neue Versionsnummer

(siehe SVN Repository Explorer). Was passiert, wenn ein anderer Entwickler die Datei bereits verändert hat? Es ist eine

Konfliktbehandlung erforderlich.

Page 33: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 33

Arbeitsschritte und Software Versionsverwaltung (Commit)

Konfliktbehandlung:1. Kopieren-Ändern-Zusammenführen-Modell

- Auschecken einer Version aus dem Projektarchiv: Eine Kopie der Daten wird auf den Client kopiert.

- Arbeit auf den Client-Dateien- Einchecken der Änderungen auf den Server: Die Änderungen werden dort

gespeichert, Konflikte müssen behoben werden. Konflikte?• Was passiert, wenn ein anderer Entwickler dieselbe Datei verändert hat?• Möglichkeiten:

– Änderungen zusammenführen– eigene Datei überschreibt die auf dem Server– eigene Änderungen werden verworfen– …

• Der SVN-Client hilft beim Zusammenführen beider Versionen.

Page 34: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 34

Arbeitsschritte und Software Versionsverwaltung (Commit)

2. Sperren-Ändern-Entsperren-Modell- Zur Konfliktvermeidung lassen sich Dateien auf dem Server gegen Änderung

sperren nicht sehr gerne gesehen (insbesondere wenn Sie in den Urlaub fahren und die Sperre vergessen).

- Bei Binärdateien, die nicht sinnvoll zusammengeführt werden können, ist das Modell aber durchaus sinnvoll.

- Häufig kann ein Administrator Sperren wieder entfernen.- Verwendung:

• Rechtsklick auf eine Datei oder ein Verzeichnis, Team und Lock… auswählen.• Danach die Dateien bearbeiten.• Abschließend nach einem Commit mit Team und Unlock… wieder freigeben.

In der Praxis hat sich gezeigt, dass das Kopieren-Ändern-Zusammenführen-Modell wenig Probleme bereitet: Nicht jeder Entwickler arbeitet gleichzeitig an allen Projektteilen.

Page 35: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 35

Arbeitsschritte und Software Versionsverwaltung (Update)

Update: Zwischenzeitliche Änderungen aus dem Repository übernehmen

Entwicklerlokale Kopie

des Quelltextes

Repository auf dem Server mit allen Versionen

des Quelltextes +zusätzlichen Binärdateien

Update

Page 36: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 36

Arbeitsschritte und Software Versionsverwaltung (Update)

Während der Arbeit oder nach einer Pause haben andere Entwickler eventuell neue Versionen im Repository abgelegt.

Vor einer Änderungen in der eigenen lokalen Kopie sollte sie aktualisiert werden, damit nicht ein alter Stand verändert wird.

Ablauf in Eclipse: Rechtsklick auf ein Paket, eine Klasse, eine Ressource oder das Projekt, dann Team und

Synchronize with Repository auswählen. Eine weitere Ansicht zeigt die Änderungen, die übernommen werden können.

Weitere Funktionen: siehe weiterführende Literatur (insbes. „Merge“ verschiedene Entwicklungszweige und Kollisionsbehandlung beim „Commit“)

Page 37: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 37

Klassen und Objekte Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 38: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 38

Klassen und Objekte Objekte

Einige Objekte im Pacman-Spiel Pacman die Geister 1 bis 4 einzelne Kirschen das Spielfeld

Einige Eigenschaften von Objekten (Zustandsinformationen) Pacman: bewegt sich nach oben, öffnet den Mund Geist 1: ist gefährlich, befindet sich auf Zelle (2,3), bewegt sich nach unten und hat eine

gewisse „Intelligenz“ Geist 2: ist gefährlich, befindet sich auf Zelle (12,5), bewegt sich nach links und hat ebenso

eine gewisse „Intelligenz“

Page 39: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 39

Klassen und Objekte Objekte

Objekte kommunizieren (Verhalten) Das Spielfeld sagt zu Pacman: „Bewege Dich nach oben“

Quellobjekt (Spielfeld) schickt dem Ziel (Pacman) eine Nachricht.

Objekte unterscheiden sich (Identität) Geist 1 ist nicht Geist 2. Alle Objekte sind eindeutig unterscheidbar!

Page 40: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 40

Klassen und Objekte Objekte

Definition: ObjektEin Objekt ist eine konkret vorhandene Einheit mit folgenden Merkmalen:

Identität: Alle Objekte lassen sich eindeutig unterscheiden (z.B. durch die Referenz). Zustand (Daten):

- Alle Attributwerte des Objektes. Der Typ der Attribute wird durch die Klasse festgelegt.

- Der Zustand ist nur durch das Objekt selbst veränder- und sichtbar, nicht aber von außen.

- Beziehungen zu anderen Objekten. Eigenschaften (Properties):

- Sie können von außen abgefragt werden.- Sie werden unter Umständen aus Daten berechnet, sind aber selbst keine Daten (z.B.

Alter = Datum - Geburtsdatum). Verhalten: Festgelegt durch Methoden der Klasse des Objektes.

Page 41: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 41

Klassen und Objekte Klassen

Definition: Klasse (im Implementierungsmodell)Eine Klasse ist die Definition der Attribut-, Eigenschaftstypen und Operationen einer Menge von Objekten.

Definition: Attribut (auch Instanzvariable genannt) Ein Attribut ist eine Eigenschaft eines Objektes. Es kann ein Datenelement oder ein berechneter Wert (=abgeleitetes Attribut) sein. Ein Attribut kommt in allen Objekten der Klasse vor. Der Wert des Attributs kann in den Objekten unterschiedlich ausfallen. Ein Attribut kann nicht ohne das zugehörige Objekt leben. Ein Attribut hat keine Identität.

In der Vorlesung wird der Begriff „Attribut“ immer für ein Datenelement verwendet.

Page 42: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 42

Klassen und Objekte Klassen

Definition: Operation Eine Operation legt fest, welche Funktionalität ein Objekt bereitstellt. Unterstützt ein Objekt eine bestimmte Operation, so sichert es einem Aufrufer zu, dass es bei

einem Aufruf die Operation ausführen wird. Durch die Signatur der Operation wird die Syntax des Aufrufs vorgegeben (Typen der

Parameterwerte). Die Operation gibt Zusicherungen darüber, welche Resultate die Operation haben wird. Die Operation beinhaltet keine Implementierung. Sie beschreibt „lediglich“ Schnittstelle

(Signatur) und Zusicherung nach außen.

Page 43: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 43

Klassen und Objekte Klassen

Definition: Methode Eine Methode ist die konkrete Implementierung einer Operation. Während Operationen die Funktionalität nur abstrakt definieren, sind Methoden für die

Realisierung dieser Funktionalität zuständig.

In der Vorlesung wird die strenge Kategorisierung von Methode und Operation nicht immer aufrechterhalten.

Hier wird häufig „Methode“ als Synonym für beide Begriffe verwendet. „Operation“ wird dort verwendet, wo es speziell auf den reinen Signaturcharakter ankommt.

Page 44: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 44

Beispiel zu Klasse und Objekt (unvollständiges Beispiel)

Klassen und Objekte Klassen und Objekte (Pacman-Beispiel)

AttributeKlassenname

Operationen

Attributwerte

Ghost

-x: int-y: int-direction: Direction+setX(x: int)+setY(y: int)+paint(cvs: Canvas, cellWidth: int, cellHeight: int)

geist1: Ghost

x = 2y = 3direction = UP

geist2: Ghost

x = 12y = 3direction = DOWN

Page 45: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 45

Klassen und Objekte Objektorientierte Sichtweise

Idee der Kapselung (Information hiding) Die Implementierung der Datenstrukturen und Algorithmen innerhalb einer Klasse wird

gegenüber den Aufrufern „versteckt“. Sie kann nach außen unsichtbar verändert werden.

Objekt

Aufruf

Attribute

Methoden

Page 46: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 46

Klassen und Objekte Objektorientierte Sichtweise

Vorteile der Kapselung: Interne Zustände und deren Abhängigkeiten bleiben nach außen verborgen Leichtere

Konsistenzhaltung der Daten. Bei Zustandsänderung müssen häufig noch andere Operationen ausgeführt werden.

Beispiel:- Im Pacman-Spiel wird die Farbe einer Figur geändert. Die Farbe ist ein Attribut der

Figur.- Danach muss die Figur neu gezeichnet werden.- Bei sauberer Kapselung wird durch die Farbänderung automatisch das Neuzeichnen

ausgelöst.

Page 47: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 47

Klassen und Objekte Objektorientierte Sichtweise

Funktioniert die Kapselung immer? Beispiel: Im Pacman-Spiel werden einzelne Figuren auf dem Spielfeld platziert. Die Figuren haben Attribute wie „Farbe“, „Bewegungsrichtung“ und „Position“. Der aktuelle Spielstand soll auf Festplatte gespeichert werden Zugriff auf die Attribute

zum Speichern notwendig. Konsequenz:

Jede Figur müsste selbst speichern Verteilung der Speicherfunktionalität auf viele Klassen sehr unschön.

Eine Klasse speichert, muss aber auf die privaten Attribute der Figuren zugreifen Aushebelung der Kapselung?

Nein: Kapselung ist immer auf einen Aufgabenbereich beschränkt. Speicherung ist eine andere Aufgabe, darf also auf die privaten Daten zugreifen. Das gilt aber nicht für Klassen, die für das Zeichnen verwendet werden.

Page 48: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 48

Klassen und Objekte Zugriffsrechte

Zugriffsrechte private: Auf private Attribute oder Methoden dürfen nur Methoden der eigenen Klasse

zugreifen. public: Auf öffentliche Attribute und Methoden dürfen alle Methoden anderer Klassen

zugreifen. protected: für Vererbung (kommt später ...) <keine Angabe>: Paketrecht (kommt später …) Die Rechte gelten auf Klassenebene: Ein Objekt einer Klasse darf auf private Attribute eines

anderen Objektes derselben Klasse zugreifen!

Page 49: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 49

Klassen und Objekte Klassen in UML

Vereinfachte Darstellung von Klassen in UML:

Attribut (Angaben in eckigen Klammern sind optional):[Sichtbarkeit][/]Name[:Typ][Multiplizität][=Vorgabewert] [{Eigenschaft}]

Sichtbarkeit/Zugriffsrecht: #: geschützt (protected) -: privat (private) +: öffentlich (public) ~: Paket (package)

AttributeKlassenname

Operationen

Ghost

- x: int- y: int- count: int

+ paint(p: Canvas, x: int, y: int)+ setX(x: int)+ setY(y: int)

statisches Attribut

Page 50: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 50

Klassen und Objekte Klassen in UML

/: Das Attribut ist eine Eigenschaft. Es wird berechnet und muss somit nicht gespeichert werden.

Name: Name des Attributs. Aufgrund von Einschränkungen vieler Programmiersprachen sollte man auf Umlaute usw. verzichten.

:Typ: Typ des Attributs Multiplizität: Anzahl Ausprägungen des Attributs

kann als Array betrachtet werden Angaben sind minimale und maximale Anzahl oder die genaue Anzahl:

- [2]: exakt zwei Werte- [1..2]: ein oder zwei Werte- [1..*]: mindestens ein Wert bis beliebig viele Werte- [0..*] bzw. [*]: beliebig viele Werte

=Vorgabewert: Initialwert für das Attribut muss zum Typ des Attributs passen bei Multiplizität größer als 1: Aufzählung in der Form {1, 2, 3, 4}

Page 51: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 51

Klassen und Objekte Klassen in UML

{Eigenschaft}: besondere Merkmale des Attributs (Auswahl) {readOnly}: Der Wert darf nach der Initialisierung nicht mehr verändert werden (eine

Konstante). {subsets <Attributname>}: Der Wert ist eine Untermenge der Werte, die in dem

Attribut <Attributname> erlaubt sind. {union}: Vereinigung aller Attributwerte, die mit subsets spezifiziert wurden. {redefines <Attributname>}: Redefiniert ein Attribut seiner Basisklasse {ordered}: Die Attributwerte müssen geordnet vorliegen. Duplikate sind nicht erlaubt. {bag}: Die Attributwerte müssen nicht geordnet vorliegen. Duplikate sind erlaubt. {seq} bzw. {sequence}: Die Attributwerte müssen geordnet vorliegen. Duplikate

sind erlaubt. {unique}: Die Attributwerte müssen nicht geordnet vorliegen. Duplikate sind nicht

erlaubt. {composite}: Das Attribut wird durch Komposition an die Klasse gebunden. Es ist so

selbst für die Zerstörung seines Inhalts verantwortlich.

Page 52: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 52

Klassen und Objekte Klassen in UML

Operation (Angaben in eckigen Klammern sind optional):[Sichtbarkeit]Name([Parameterliste])[:Rückgabetyp] [{Eigenschaft}]

Sichtbarkeit/Zugriffsrecht: wie bei Attributen Name: wie bei Attributen Parameterliste mit dem folgenden Aufbau:

[Übergabemodus] Name :Typ [Multiplizität][=Vorgabewert][{Eigenschaft}] Übergabemodus (unvollständig):

- in: Der Parameter wird von der Operation nur gelesen. Fehlt der Modus, so wird in angenommen. In Java nur für primitive Datentypen möglich.

- out: Der Parameter wird von der Operation nur geschrieben. Umsetzungsmöglichkeit in Java nur für Objekte (Besonderheit String StringBuffer, …)

- inout: Der Parameter wird von der Operation gelesen und geschrieben. Umsetzungsmöglichkeit in Java nur für Objekte.

Page 53: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 53

Klassen und Objekte Klassen in UML

Name: Name des Parameters :Typ: Typ des Parameters Multiplizität: Anzahl Ausprägungen des Parameters, die übergeben werden. Die

Angaben erfolgen wie bei Attributen. Umsetzungsmöglichkeit in Java: Arrays =Vorgabewert: Wert, den der Parameter erhält, wenn er nicht übergeben wird.

Umsetzung in Java nicht direkt möglich. {Eigenschaft}: siehe Attribute

:Rückgabetyp: Typ des Rückgabewertes, fehlt dieser, so wird void angenommen. Die Angabe void ist nicht erlaubt.

{Eigenschaft}: Angabe spezieller Merkmale des Rückgabetyps, siehe Attribute. Und was ist mit Ausnahmen (Exceptions)? UML kennt sie nicht. Ausweg in Form eines

Eigenschaftswertes (Tagged Value):{raisedException=NameDerAusnahme}Andere, eigene Eigenschaftswerte sind auch erlaubt sinnvoll bei MDA.

Page 54: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 54

Klassen und Objekte Klassen in UML (Pacman-Beispiel)

Klasse für eine Zelle des Spielfeldes (unvollständig):

Weitere Klassen kommen erst später, weil sie Vererbung bzw. Beziehungen zwischen Klassen benötigen.

Cell

- border: int- food: boolean- exit: boolean

+ paint(cvs: Canvas, x: int, y: int)+ isFood(): boolean+ isExit(): boolean+ getBorder(): int

Page 55: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 55

Klassen und Objekte Klassen allgemein

Typen von Klassen Statisches Typsystem (C++, C#, Java, …):

Der Typ von Variablen und Parametern wird im Quelltext festgelegt. Vorteile:

- bessere Optimierung durch den Compiler möglich- saubere Programmstruktur, da Typen direkt im Quelltext ersichtlich sind- gute Unterstützung durch IDEs, da diese die Variablentypen erkennen- frühzeitige Fehlererkennung durch den Compiler

Dynamisches Typsystem (z.B. JavaScript): Variablen können beliebige Daten aufnehmen. Der Variablentyp steht erst zur Laufzeit fest. Eigenschaften („Vorteile“):

- Werte können von beliebigem Typ sein automatische Konvertierung- Ducktyping: Wenn es watschelt wie eine Ente, wenn es schwimmt wie eine Ente,

wenn es quakt wie eine Ente, dann behandeln wir es wie eine Ente.

Page 56: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 56

Klassen und Objekte Klassen allgemein

Stark und schwach typisierte Programmiersprachen Stark typisierte Sprache: Überwacht das Erstellen und den Zugriff auf alle Objekte so, dass

sichergestellt ist, dass Referenzen/Zeiger immer auf Objekte verweisen, die auch die Spezifikation des Typs erfüllen, der für die Variable deklariert ist. Beispiel: Java

Schwach typisierte Sprachen: Zeiger können auf Objekte verweisen, ohne dass das Objekt notwendigerweise die Spezifikation des Typs der Variablen erfüllt. Beispiel: C++

Page 57: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 57

Klassen und Objekte Klassensyntax in Java

Syntax von Klassen in Java Eine Klasse kapselt Attribute, Operationen und eventuell Operatoren als eine Einheit. Beispiel zu Attributen und Methoden:

public class Cell { private int border; private boolean food; private boolean exit;

public int getBorder() { return border; }}

Hinweis: Statt „Methode“ wird häufig auch der Begriff „Funktion“ verwendet. Statt „Attribut“ werden auch häufig „Instanzvariable“ oder „Variable“ verwendet.

Page 58: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 58

Alle Attributzugriffe sollten immer über Methoden mit gleichem Namen mit vorangestelltem get bzw. set erfolgen Kapselung!Beispiel:public class Cell { private int border; private boolean food;//... public int getBorder() { return border; } public boolean isFood() { return food; } public void setBorder(int nBorder) { border = nBorder; } public void setFood(boolean nFood) { food = nFood; }}

Klassen und Objekte Attributzugriffe

falls der Lese- und Schreibzugriff erlaubtsein soll Namensvergabenach Java-Konvention

Page 59: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 59

Klassen und Objekte Beispiel (Vektor, Version 1)

Aus der Mathematik bekannt: Vektoren und Matrizen. Klasse Vector, hier eingeschränkt auf Länge 3 mit double-Zahlen (noch unvollständig und

gefährlich kommt später besser):

package de.hska.iwii.i2;

public class Vector { private double[] values = new double[ 3 ];

public void setValue(int index, double value) { values[ index ] = value; }

public double getValue(int index) { return values[ index ]; }}

Vector

- values: double[3] {bag}

+ setValue(index: int, double: value)+ getValue(index: int): double

package de.hska.iwii.i2;

public class VectorTest { public static void main( String[] args) { Vector v1 = new Vector(); v1.setValue(0, 2.0); System.out.println(v1.getValue(0)); }}

Page 60: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 60

Klassen und Objekte Konstruktoren

Definition: KonstruktorKonstruktoren dienen der gezielten Initialisierung eines Objektes bei dessen Erzeugung.

Es kann mehr als einen Konstruktor in einer Klasse geben.Beispiel (Vector, Version 2):public class Vector { private double[] values;

public Vector(int size) { values = new double[ size ]; }

public void setValue(int index, double value) { values[ index ] = value; } public double getValue(int index) { return values[ index ]; }}

Page 61: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 61

Klassen und Objekte Konstruktoren

Ein Konstruktor darf auch einen anderen aufrufen:public class Vector { // ... public Vector(int size) { this(size, 0.0); }

public Vector(int size, double initValue) { values = new double[ size ]; for (int i = 0; i < size; ++i) { values[ i ] = initValue; } } // ...}

Ohne die Angabe eines Konstruktors wird immer automatisch der Defaultkonstruktor (ohne Parameter) erzeugt (sonst nicht).

Ein Konstruktor wird immer automatisch aufgerufen, wenn ein Objekt der Klasse erzeugt wird.

Page 62: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 62

Klassen und Objekte Beispielmethode zur Skalarproduktberechnung

Skalarprodukt (immer noch Version 2), fehlerhaft:public class Vector { // ...

public double getScalarProduct(Vector second) { double result = 0.0; for (int i = 0; i < values.length; ++i) { result += values[ i ] * second.values[ i ]; }

return result; }

// ...}

Page 63: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 63

Klassen und Objekte Variable Anzahl Übergabeparameter

Probleme: Eine Methode oder ein Konstruktor wird mit einer beliebigen Anzahl Werte desselben

Typs aufgerufen. Lösungen:

- Alle Werte kommen in ein Array. Das Array wird übergeben.- Java unterstützt die Übergabe einer variablen Parameteranzahl.

Beispiel Konstruktor des Vektors mit variabler Anzahl double-Werte:public class Vector { private double[] values;

public Vector(double... initValues) { values = new double[initValues.length]; for (int i = 0; i < initValues.length; ++i) { values[ i ] = initValues[ i ]; } } // ...}

Page 64: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 64

Klassen und Objekte Variable Anzahl Übergabeparameter

Aufrufe:Vector v1 = new Vector(1.0, 2.0, 3.0, 4.0); // Länge 4Vector v2 = new Vector(1.0, 2.0); // Länge 2Vector v3 = new Vector(); // Länge 0

Intern werden die Parameter in einem Array abgelegt: Die Anzahl der Parameter kann mit array.length ermitteln werden. Die Parameter werden mit Array-Zugriffen ausgelesen.

Das funktioniert auch für Methoden.

Page 65: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 65

Klassen und Objekte Aufbau und Verwendung von Klassen

Klassen kapseln Daten und arbeiten selbst auf ihren eigenen Daten:“Don't ask for the information that you need to do something; rather, ask the object that has that information to do the job for you.”

Beispiel (so nicht):public class Article { private double price;

public double getPrice() { return price; } // usw.}

// Implementierung einer Preiserhöhung in einer anderen Klassepublic void increasePrice(Article article, double percentage) { article.setPrice(article.getPrice() * (1 + percentage / 100.0));}Problem: Lesen, Manipulation und Schreiben von Article-Daten. Die Article-Operation gehört in die Klasse!

Page 66: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 66

Klassen und Objekte Aufbau und Verwendung von Klassen

Beispiel (so ist es ok):public class Article { private double price;

public double getPrice() { return price; } // usw. // Implementierung einer Preiserhöhung public void increasePrice(double percentage) { price *= (1 + percentage / 100.0)); }}

Page 67: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 67

Klassen und Objekte Statische Attribute und Methoden

Bisher: Jedes Attribut einer Klasse existiert in jedem Objekt der Klasse. Manchmal gewünscht: Auch „globale“ Attribute, die nur einmal für eine Klasse existieren

Alle Objekte einer Klasse teilen sich dieses Attribut:static Typ Attribut-Name;

Zugriff auf statische Attribute: Statische Methoden: static Typ Methode(Parameter);

Aufruf einer statischen Methode einer Klasse auch ohne ein konkretes Objekt. Statische Attribute können als globale Attribute innerhalb einer Klasse betrachtet werden.

Beispiel kommt nachher im Rahmen der Einführung von Referenzen.

Page 68: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 68

Klassen und Objekte final-Parameter und final-Werte

final-Parameter und final-Werte können nicht verändert werden Konstante!Beispiel: public void add(final int arg) { // ...}

final Vector vector: Unveränderliche Referenz auf ein Vektor-Objekt, dessen Inhalt aber verändert werden kann.

Page 69: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 69

Klassen und Objekte Parameterübergabe bei primitiven Datentypen

Parameterübergabe (primitive Datentypen) Werte primitiver Datentypen werden immer per Wert übergeben. Es wird eine lokale Kopie

erzeugt. Änderungen am Wert innerhalb einer Methode wirken nicht nach außen.Beispiel:public void doSomething(int xx){ xx = 2; }

public int doSomethingElse(){ int x = 21; doSomething(x); System.out.println(x); return 0; }Ausgabe: 21

Page 70: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 70

Klassen und Objekte Parameterübergabe bei Objekten

Parameterübergabe (Objekte) Objekte werden nicht übergeben. Statt dessen werden Kopien von Referenzen auf Objekte

übergeben werden. Damit sind Änderungen nach außen sichtbar. Beispiel:public void doSomething(Vector v){ v.setValue(0, 42); }

public int doSomethingElse(){ Vector v = new Vector(3); doSomething(v); System.out.println(v.getValue(0)); return 0; }Ausgabe: 42

Zusatznutzen einer Referenzkopie: Das Anlegen einer Objekt-Kopie kann zeitaufwändig sein. Hinweis: Die übergebenen Objekte sollte möglichst nicht verändert werden. Die Rückgabe

eines Wertes ist ein sauberer Weg andere Lösung: „Value Objects“ (kommt gleich)

Page 71: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 71

Klassen und Objekte Ergebnisrückgabe

Es gilt dasselbe wie bei Übergaben: Werte primitiver Datentypen werden als Kopie und Objekte per Kopie der Referenz auf das Objekt zurückgegeben.

Page 72: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 72

Klassen und Objekte Parameterübergabe bei Objekten: „Value Objects“

Es werden nur Referenzen auf Objekte übergeben, keine Kopien der Objekte. Vorteile:

Effizienter als Kopie der Objekte Einfacher Mechanismus

Problem: Die aufgerufene Methode kann das Objekt verändern, ohne dass es der Aufrufer erfährt!

Verhinderung des Problems: Übergabe unveränderlicher Objekte als „Wert-Objekte“ („Value Objects“)

Alle Attribute sind Konstanten. Es gibt keine Methoden, die das Objekt verändern. Bei jedem Veränderungsversuch wird ein neues Objekte erstellt, das alte aber

unverändert beibehalten. Konsequenz: Erst einmal ein gewisser Mehraufwand zur Laufzeit führt in bestimmten

Situationen („Multithreading“, kommt im dritten Semester) aber zu deutlichen Vereinfachungen

Später im Semester: unveränderliche Datenstrukturen

Page 73: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 73

Klassen und Objekte Parameterübergabe bei Objekten: „Value Objects“

Beispiel unveränderlicher Vektor (Projekt Vector 2 (Value Objects)):public class Vector { // Achtung: Die Werte im Array sind immer noch veränderlich! private final double[] values;

public Vector(int size, double initValue) { values = new double[ size ]; for (int i = 0; i < size; ++i) { values[ i ] = initValue; } }

public Vector(double... initValues) { values = new double[initValues.length]; for (int i = 0; i < initValues.length; ++i) { values[ i ] = initValues[ i ]; } }

Attribut darf im Konstruktoreinmal verändert werden,obwohl es final ist.

Page 74: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 74

Klassen und Objekte Parameterübergabe bei Objekten: „Value Objects“

/** * Vektor unverändert lassen, neuen Vektor erzeugen! * @param index Index des zu verändernden Wertes. * @param value Neuer Wert am Index. * @return Neuer Vektor mit verändertem Wert. */ public Vector setValue(int index, double value) { // Die Kopie des Vektors würde man durch die // clone-Methode erstellen --> noch nicht bekannt. Vector copy = new Vector(values); copy.values[ index ] = value; return copy; }

public double getValue(int index) { return values[ index ]; }}

Page 75: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 75

Klassen und Objekte Parameterübergabe bei Objekten: „Value Objects“

„Value Objects“ sind im JDK nicht sonderlich verbreitet. Es gibt aber andere Klassenbibliotheken, die dieses Entwurfsmuster einsetzen kommt

später im Datenstruktur-Kapitel. Die Vorteile von „Value Objects“ werden aber häufig erst im Zusammenhang mit

Multithreading deutlich.

Page 76: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 76

Für die primitiven Datentypen existieren Wrapper-Klassen

Typ Größe Wertebereich Wrapper

boolean true, false Booleanchar 16 Bit '\u0000'‚ bis '\uFFFF' Characterbyte 8 Bit -27 bis 27-1 Byteshort 16 Bit -215 bis 215-1 Shortint 32 Bit -231 bis 231-1 Integerlong 64 Bit -264 bis 264 – 1 Longfloat 32 Bit 2-149 bis (2-2-23)·2127 Floatdouble 64 Bit 2-1074 bis (2-2-52)·21023 Doublevoid Void

Klassen und Objekte Primitive Datentypen und Wrapper-Klassen

Page 77: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 77

Klassen und Objekte Primitive Datentypen und Wrapper-Klassen

Eigenschaften der Wrapper Sie kapseln einen Wert eines primitiven Datentyps (ein Integer-Objekt nimmt genau einen

int-Wert auf). Der gekapselte Wert ist unveränderlich. Sie besitzen Methoden zur Konvertierung vom/in den Wrapper.Wozu dienen die Wrapper? Manche Methoden und Klassen erwarten Objekte und keine primitiven Datentypen die

Wrapper kapseln die Daten dazu. Beispiel aus dem 1. Semester: Eine ArrayList mit int-Werten kann so verwendet

werden:ArrayList<Integer> daten = new ArrayList<>(); // primitive Datentypen sind // nicht möglichdaten.add(500); // wird automatisch zu // daten.add(Integer.valueOf(500));

Page 78: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 78

Klassen und Objekte Primitve Datentypen und Wrapper-Klassen

Automatisches Einpacken mit Wrappern (autoboxing) Automatisches „Einpacken“ (siehe vorheriges Beispiel)

ArrayList<Integer> daten = new ArrayList<>();daten.add(66); // autoboxingdaten.add(42); // autoboxingdaten.add(1); // autoboxing

4266

daten1

Integer IntegerInteger

add

1Integer

Page 79: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 79

Klassen und Objekte Primitive Datentypen und Wrapper-Klassen

Was passiert genau? Für die ganze Zahlen -128 bis 127 existieren vordefinierte Wrapper-Objekte, die

verwendet werden. Für andere Zahlenbereiche sowie float und double werden jeweils neue Objekte

erzeugt Probleme beim Vergleichen:Integer boxedKlein1 = 127;Integer boxedKlein2 = 127;System.out.println(boxedKlein1 == boxedKlein2);   // true

Integer boxedKlein1 = 128;Integer boxedKlein2 = 128;System.out.println(boxedKlein1 == boxedKlein2);   // false

Page 80: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 80

Klassen und Objekte Primitive Datentypen und Wrapper-Klassen

Automatisches Auspacken mit Wrappern (unboxing) Automatisches „Auspacken“

ArrayList<Integer> daten = new ArrayList<>();daten.add(66); // autoboxingdaten.add(42); // autoboxingdaten.add(1); // autoboxingint wert = daten.get(0); // unboxing

4266

daten66

Integer IntegerInteger 1Integer

Page 81: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 81

Klassen und Objekte Primitive Datentypen und Wrapper-Klassen

Was passiert genau? Eine null-Referenz kann nicht umgewandelt werden und führt zu einer Exception:

int zahl = (Integer) null;    // führt zu einer NullPointerException Es lauern Fallen bei der Umwandlung von Zahlen:

Integer i1 = new Integer(42);Integer i2 = new Integer(42);System.out.println(i1 >= i2);   // true, unboxing in int-WerteSystem.out.println(i1 <= i2);   // true, unboxing in int-WerteSystem.out.println(i1 == i2);   // false, Vergleich der Referenzen!

Page 82: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 82

Klassen und Objekte Innere Klassen

Klassen lassen sich ineinander schachteln. Java unterstützt drei unterschiedliche Arten innerer Klassen:

nicht-statische innere Klassen statische innere Klassen anonyme innere Klassen

Einsatzgebiete: Die inneren Klassen werden hauptsächlich in der äußeren benötigt oder von dieser

erzeugt. Beispiel (kommt später): Iteratoren

Aussen

Innen

-attribut: int

public class Aussen { class Innen { int attribut; // ... } // ... }

Page 83: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 83

Klassen und Objekte Innere Klassen: Nicht-statische innere Klassen

Einsatz: Das Erzeugen eines Objektes der inneren Klasse erfolgt immer innerhalb der Grenzen der äußeren Klasse (z.B. in einer der Methoden oder im Konstruktor).

Beispiel:public class Outer { class Inner { private int attr1; public void method1(){} public void method2(){ method1(); Outer.this.method1(); } } public void method1(){}}

Innere Klassen dürfen weder statische Methoden noch statische Attribute besitzen. Outer darf auf alle Methoden und Attribute von Inner zugreifen. Inner darf auf alle Methoden und Attribute von Outer zugreifen. Innere und äußere Klasse sind somit fest miteinander verbunden. Erzeugte Dateien: Outer.class, Outer$Inner.class

Page 84: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 84

Klassen und Objekte Innere Klassen: Statische innere Klassen

Einsatz: Das Erzeugen eines Objektes der inneren Klasse kann außerhalb der Grenzen der äußeren Klasse erfolgen.

Beispiel:public class Outer { static class Inner { private int attr1; public void method1(){} public void method2(){ method1(); } } private int attr2; public void method1(){}}

Die innere Klasse ist nicht an die äußere gekoppelt und kann daher nicht auf Attribute und Methoden der äußeren Klasse zugreifen.

Erzeugte Dateien: Outer.class, Outer$Inner.class

Page 85: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 85

Klassen und Objekte Innere Klassen: Anonyme innere Klassen

Einsatz: Mit dem Erzeugen einer Klasse wird auch gleichzeitig ein Objekt angelegt. Die Klasse wird nur einmalig benötigt.

Häufig im Zusammenhang mit dem Implementieren von Schnittstellen verwendet: Beispiel:

public class Outer { public void method() { Runnable runObject = new Runnable() { @Override public void run() { System.out.println("Huhu"); } }; runObject.run(); }}

Runnable ist eine Schnittstelle kommt noch genauer Die anonyme Klasse darf nur auf finale lokale Variablen der Methode zugreifen. Die anonyme Klasse darf auf Attribute und Methoden der äußeren Klassen zugreifen. Erzeugte Dateien: Outer.class, Outer$1.class

Page 86: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 86

Klassen und Objekte Pakete

Probleme: Was passiert, wenn zwei Hersteller Klassen mit demselben Namen erstellt haben und

beide Klassen in einem Projekt zusammen benutzt werden sollen? Wie können logisch zusammengehörige Klassen gruppiert werden?

Ein Paket sollte eine Anzahl logisch zusammengehöriger Klassen, Schnittstellen, Ausnahmen, Fehler, Aufzähltypen und Annotationen beinhalten.Beispiel:

alle Klassen, die mathematische Berechnungen durchführen alle Klassen, die Text formatieren

Der Paketname entspricht einem Verzeichnis im Dateisystem.Beispiel:Klasse Complex im Paket de.hska.iwii.math: Sowohl die Quelltextdatei Complex.java als auch die Bytecode-Datei Complex.class sollten in in einem Unterverzeichnis de/hska/iwii/math liegen.

Festlegung der Paket-Zugehörigkeit einer Klasse: Anweisung in der Klasse der Form package Paket-Name;. Diese Anweisung sollte die erste in der Datei sein.

Page 87: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 87

Klassen und Objekte Pakete: Verwendung

Verwendung einer Klasse eines anderen Pakets: Variante 1: import Paketname.*; Beispiel:

import de.hska.iwii.math.*; // Bindet alle Klassen des Pakets// de.hska.iwii.math ein

//...Complex value = new Complex();

Variante 2: import Paketname.Klassenname; Beispiel:import de.hska.iwii.math.Complex; // Bindet Complex des Pakets

// de.hska.iwii.math ein.//...Complex value = new Complex();

Variante 3: Verwendung des vollständigen Klassennamens. Beispiel://...de.hska.iwii.math.Complex value = new de.hska.iwii.math.Complex();

Nach Aussage von Oracle sollte Variante 1 vermieden werden. Das Paket java.lang des JDK ist immer automatisch eingebunden.

Page 88: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 88

Klassen und Objekte Pakete: Namensaufbau

Allgemeiner Aufbau eines Namens (kann variieren):Organisation.Paketname.Klassenname.MethodennameBeispiele:

de.hska.ss2012.project2.math.Complex.add()

com.mycompany.math.Complex.add()

javax.swing.table.DefaultTableModel.getDataVector()

Paket Klasse Methode

Land Hoch-schule

KA

Semester Projekt Teil desProjektes

Kommer-ziell

Firma Teil desProjektes

Paket Klasse Methode

Zusatz-klasse

des JDK

GUI-Paket

Tabelle

Paket Klasse Methode

Page 89: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 89

Klassen und Objekte Pakete

Innerhalb eines Pakets müssen die Namen eindeutig sein: Es darf eine Klasse Complex mehrfach geben, solange sie in unterschiedlichen Paketen liegt.

Beispiel: java.util.Timer und javax.swing.Timer So ganz stimmt die Aussage nicht:

Der komplette Paketname (der Pfad inkl. Klassenname) darf mehrfach vorkommen, wenn die Pakete durch unterschiedliche Klassenlader (Classloader) geladen werden.

Also: Klassenlader + Paketname muss eindeutig sein! Es ist mindestens ein Klassenlader in der virtuellen Maschine aktiv:

Er kennt mehrere Dateipfade oder jar-Dateien, aus denen er die Klassen und Schnittstellen lädt.

Weitere Klassenlader können erstellt und verwendet werden.

Page 90: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 90

Fehlererkennung Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 91: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 91

Fehlererkennung Fehlerhafte Methodenaufrufe

Idee: Die eigenen Methoden und Klassen werden eventuell falsch oder mit falschen Daten aufgerufen.

Auch wenn der eigene Algorithmus korrekt ist, darf er nicht durch falsche Werte durcheinander geraten.

Denn: Programme werden im Laufe der Zeit permanent verändert. Fehler können daher immer wieder einmal auftreten.

Konsequenz: Ein Profi sichert seine eigenen Klassen und Methoden gegen eine fehlerhafte Verwendung ab.

In Kombination mit einem sauberen Software-Entwurf und anschließenden Tests, stellt die defensive Programmierung einen wichtigen Schritt in Richtung stabiler Programme dar.

Der Anwender sollte Programmfehler nie zu Gesicht bekommen.

Page 92: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 92

Fehlererkennung Fehlerhafte Methodenaufrufe

3 Strategien zur Parameterbehandlung: Müll rein – nichts raus Müll rein – Fehlernachricht raus Müll rein – Müll raus (nicht akzeptabel!)

Daher: Prüfen aller Eingabeparameter Numerische Werte innerhalb vorgegebener Toleranzen Maximale Länge von Strings Randbedingungen wie 0, "", null usw.

Festlegen und dokumentieren, wie fehlerhafte Parameter behandelt werden sollen: Rückgabe eines Fehlercodes (false, -1, ...). Besser: Ausnahmen Aufruf einer Fehlerbehandlungsroutine Eintrag in einer Protokolldatei erstellen Programm beenden

Page 93: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 93

Fehlererkennung Fehlerhafte Methodenaufrufe

Kontrakt zwischen einer Klasse und den Nutzern einer Klasse: Beschreibt, welche Voraussetzungen (Vorbedingungen) ein Aufrufer der Operation

schaffen muss, damit die Operation durchgeführt werden kann. Legt fest, welche Leistung (Nachbedingungen) die Operation erbringt, sofern die

Vorbedingungen eingehalten sind. Vorbedingungen (engl. Preconditions)

Der Aufrufer der Operation ist verpflichtet, diese Bedingungen beim Aufruf der Operation herzustellen.

Sind die Vorbedingungen nicht erfüllt, ist die Operation nicht verpflichtet, ihre spezifizierte Aufgabe zu erfüllen.

Vorbedingungen sind damit der Kontraktbestandteil, den der Aufrufer einer Operation einzuhalten hat.

Sind die Vorbedingungen eingehalten, ist der Aufgerufene wiederum verpflichtet, die Nachbedingungen herzustellen.

Page 94: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 94

Fehlererkennung Fehlerhafte Methodenaufrufe

Nachbedingungen (engl. Postconditions) Eine Klasse, die eine Operation implementiert, sichert zu, dass die Nachbedingungen

unmittelbar nach Aufruf der Operation gelten. Die Zusicherung gilt nur, wenn der Aufrufer die für die Operation definierten

Vorbedingungen eingehalten hat. Zusätzlich können auch nach außen zugesicherte Bedingungen vereinbart sein, die immer

gelten sollen, unabhängig vom Aufruf einer Operation. Invarianten (engl. Invariants)

Invarianten sind Eigenschaften und Beziehungen zwischen Attributen eines Objekts, die sich durch keine Operation ändern lassen.

Invarianten, die für eine Klasse definiert werden, gelten für alle Objekte der Klasse.

Page 95: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 95

Fehlererkennung Fehlerhafte Methodenaufrufe

Deklaration von Bedingungen in UML Ziel: möglichst automatische Überprüfbarkeit im späteren Quelltext Einführung der Object Constraint Language (OCL)

Object Constraint Language (OCL) Die OCL wird verwendet, um zusätzliche Bedingungen darzustellen, die sich mit den

sonstigen Beschreibungsmitteln der UML nicht oder nur umständlich ausdrücken lassen. OCL stellt dabei eine rein deklarative Beschreibungsmöglichkeit zur Verfügung, um

sogenannte Constraints auszudrücken. Ein Constraint ist ein Ausdruck, der entweder wahr oder falsch ist. OCL eignet sich sehr gut, um Vorbedingungen, Nachbedingungen und Invarianten von

Operationen auszudrücken. Hier: keine vollständige Einführung in OCL

Page 96: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 96

Fehlererkennung Fehlerhafte Methodenaufrufe

Beispiel zu OCL:

Wozu Constraints? Im Quelltext sind sie doch sowieso nicht sichtbar. Falsch: Mit Assertions (Zusicherungen) lassen sich Vorbedingungen manuell überprüfen. Einhaltung der Vorbedingungen können mit http://sourceforge.net/projects/ocl4java/

automatisch überwacht werden.

Account

- number: int- balance: int

+ payOff(amount: int)

context Account::payOff

pre: balance >= amount

post: balance = balance - amount

Page 97: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 97

Zusicherungen Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 98: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 98

Zusicherungen Fehlerhafte Methodenaufrufe

Idee: Jede Funktion oder Methode schützt sich selbst gegen beispielsweise falsche Aufrufparameter oder falsche Zustände.

Realisierung: Die Anweisung assert wird zur Prüfung der Vor- und Nachbedingungen einer Methode

verwendet. Sie wertet eine übergebene Bedingung aus. Ist diese falsch, so wird das Programm mit

einem AssertionError beendet. Beispiel Methode sqrt:

public double sqrt(double value) { assert value >= 0.0; // Nicht negativ // Wurzelberechnung}

Aufruf mit: x.sqrt(42.0); // OK x.sqrt(-66.66); // Abbruch

Page 99: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 99

Zusicherungen Fehlerhafte Methodenaufrufe

Verwendungen: assert Bedingung;

- Der Ausdruck muss einen Boole‘schen Wert ergeben.- Ist der Wert false, so wird dieses als Fehler betrachtet.- Ist der Wert true, so wird das Programm normal fortgesetzt.assert value >= 0.0;

assert Bedingung : Meldungstext;- Es gelten die Aussagen wie im ersten Fall.- Zusätzlich wird hier ein Text übergeben, der in die Ausnahme aufgenommen wird.assert value >= 0.0 : "Die Wurzel aus neg. Zahlen ist undefiniert."

Assertions müssen aktiviert werden:- Alle aktivieren: java -ea Main.class- Nur im Paket de.hska und dessen Unterpaketen: java -ea:de.hska...

Sind Assertions nicht aktiv, dann werden sie ignoriert.

Page 100: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 100

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Programmierung einessehr einfachen Ticketautomaten:

Der Preis erscheint auf dem Display (Einheitspreis in Cent).

Der Kunde zahlt solange mit Münzen oder Scheinen, bis der Betrag erreicht ist (es wird kein Wechselgeld ausgezahlt).

Nach dem Geldeinwurf wird der Restbetrag angezeigt.

Nach Erreichen des Betrags wird der Fahrschein ausgegeben.

[https://commons.wikimedia.org/wiki/Category:Ticket_machines?uselang=de#/media/File:Ascom_B8050_Quickfare_Machine_at_Wareham_Station_%282006%29.jpg]

Page 101: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 101

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Benötigte Attribute: int ticketPrice: Preis für ein Ticket int paidPrice: bereits bezahlter Preis

Benötigte Methoden, 1. Versuch: Konstruktor: Einheitspreis als int-Parameter flexibel void requestTicket(): Ticket anfordern int requestPrice(): (Rest-)Preis für das Ticket abfragen void insertMoney(int amount): Geld einwerfen void printTicket(): Ticket ausdrucken

Page 102: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 102

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Klasse in UML:

TicketMachine

-ticketPrice: int-paidPrice: int

+TicketMachine(price: int)+requestTicket()+requestPrice(): int+insertMoney(amount: int) +printTicket()

context TicketMachine::printTicketpre: paidPrice >= ticketPricepost: paidPrice = 0

context TicketMachine::requestTicketpost: paidPrice = 0context TicketMachine::insertMoneypre: amount > 0post: paidPrice = paidPrice + amount

context TicketMachine::TicketMachinepre: price > 0post: (ticketPrice = price and paidPrice = 0)

Page 103: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 103

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Quelltext:public class TicketMachine { // Die Attribute der Klasse private int ticketPrice; private int paidPrice;

// Konstruktor zum Initialisieren public TicketMachine(int price) { ticketPrice = price; paidPrice = 0; }

// Ticket anfordern --> löscht den bisher bezahlten Betrag public void requestTicket() { paidPrice = 0; }

// (Noch) zu zahlenden Betrag anfordern. public int requestPrice() { return ticketPrice – paidPrice; }

Page 104: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 104

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

// Geld einwerfen --> Restbetrag reduzieren. public void insertMoney(int amount) { paidPrice += amount; }

// Ticket "ausdrucken" public void printTicket() { System.out.println("Ticket xyz"); System.out.println("Preis: " + ticketPrice); paidPrice = 0; }}

Page 105: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 105

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Eine perfekte Lösung Nein!!! Probleme:

Keine Prüfungen der Methodenparameter und internen Zustände:- negative Beträge eingeworfen- Ticket drucken, obwohl Endbetrag nicht erreicht wurde- Was passiert, wenn zu viel Geld eingeworfen wurde?- Der Ticketpreis im Konstruktor ist ungeprüft.

Einhaltung der Vorbedingungen wurde nicht geprüft!!!

Page 106: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 106

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

Quelltext mit Prüfungen:public class TicketMachine {

// Die Attribute der Klasse private int ticketPrice; private int paidPrice;

// Konstruktor zum Initialisieren public TicketMachine(int price) { assert price > 0; ticketPrice = price; paidPrice = 0; }

// Ticket anfordern --> löscht den bisher bezahlten Betrag public void requestTicket() { paidPrice = 0; }

context TicketMachine::TicketPricepre: price > 0post: (ticketPrice = price and paidPrice = 0)

context TicketMachine::requestTicketpost: paidPrice = 0

Page 107: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 107

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

// (Noch) zu zahlenden Betrag anfordern. public int requestPrice() { return ticketPrice – paidPrice; }

// Geld einwerfen --> Restbetrag reduzieren. // Zuviel bezahlten Betrag wieder auswerfen. public int insertMoney(int amount) { assert amount > 0; int diff = ticketPrice – paidPrice - amount; paidPrice += amount; if (paidPrice > ticketPrice) paidPrice = ticketPrice; return diff >= 0 ? 0 : -diff; }

context TicketMachine::insertMoneypre: amount > 0post: paidPrice = min(paidPrice + amount, ticketPrice)

Page 108: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 108

Zusicherungen Fehlerhafte Methodenaufrufe: Ticketautomat

// Ticket "ausdrucken" public void printTicket() { assert paidPrice >= ticketPrice; System.out.println("Ticket xyz"); System.out.println("Preis: " + ticketPrice); paidPrice = 0; }}

context TicketMachine::printTicketpre: paidPrice >= ticketPricepost: paidPrice = 0

Page 109: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 109

Klassen und Objekte Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 110: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 110

Klassen und Objekte Beispiel: Ringpuffer

Eine erste einfache Implementierung eines Ringpuffers: Ein Ringpuffer kann als ein Array mit speziellen Lese- und Schreiboperationen

interpretiert werden: Das Array dieses Ringpuffers kann nur int-Daten aufnehmen. Ein Leseindex RI zeigt die Position an, an der der nächste Wert gelesen wird. Nach dem

Lesen wird der Index automatisch erhöht. Am Ende des Arrays wird der Index auf 0 gesetzt. Somit handelt es sich um ein zerstörendes Lesen, bei dem der Wert nach dem Lesen nicht mehr im Ringpuffer zugreifbar ist.

Ein Schreibindex WI zeigt die Position an, an die der nächste Wert geschrieben wird. Nach dem Schreiben wird der Index automatisch erhöht. Am Ende des Arrays wird der Index auf 0 gesetzt.

Der Ringpuffer ist leer, wenn WI genauso groß wie RI ist. Der Ringpuffer ist voll, wenn gilt: WI hätte nach dem Erhöhen den Wert von RI.

Bessere Variante: siehe Übungsaufgabe

Page 111: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 111

Klassen und Objekte Referenzen und dynamische Speicherverwaltung

Warum kann man Objekte und Variable nicht einfach alle auf dem Stack verwalten? Wie werden Objekte auf dem Heap erzeugt und wieder freigegeben? Referenzen sind spezielle Variable, die auf Objekte verweisen. Zum Bau komplexer Datenstrukturen sind der Heap und Referenzen zwingend

notwendig.

Page 112: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 112

Klassen und Objekte Referenzen und dynamische Speicherverwaltung

Definition: ReferenzEine Referenz hat einen unveränderlichen Typ T. Sie enthält einen Verweis auf genau ein oder gar kein Objekt der Klasse T. Das Objekt liegt auf dem Heap.

Beispiel für eine Referenz, die auf kein Objekt verweist:Bruch brReferenz = null;

Beispiel für eine Referenz auf ein Bruch-Objekt:Bruch brReferenz = new Bruch(2,3);

Intern enthält die Referenz die Speicheradresse des Objektes. Es existieren zwei Referenzen mit einer besonderen Semantik:

null: Die Referenz verweist auf gar kein Objekt. this: Die Referenz verweist auf die eigene Objektinstanz (kann nur in Konstruktoren

oder nicht-statischen Methoden verwendet werden). Es gibt auch sogenannte schwache Referenzen, die hier aber nicht betrachtet werden sollen.

Page 113: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 113

Klassen und Objekte Referenzen und dynamische Speicherverwaltung

Definition: HeapSpeicherbereich, in dem der Entwickler selbst die Lebensdauer seiner Daten kontrolliert. Mit new wird ein Bereich reserviert. Die Freigabe erfolgt automatisch durch den Garbage-Collector.

Der Operator new führt die folgenden Schritte durch: Reservierung des benötigten Speichers auf dem Heap Aufruf eines Konstruktors Rückgabe einer Referenz auf das erzeugte Objekt

Anforderung eines Speicherbereichs mit Aufruf des Defaultkonstruktors:Syntax: Beispiel:Klasse ref = new Klasse(); Pacman pacmanRef = new Pacman();

Anforderung eines Speicherbereichs mit Aufruf eines beliebigen Konstruktors:Syntax: Beispiel:Klasse ref = new Klasse(init); Pacman pacmanRef = new Pacman(x, y);

Page 114: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 114

Klassen und Objekte Referenzen und dynamische Speicherverwaltung – new-Operator

Der Operator new führt die folgenden Schritte bei Arrays durch: Reservierung des benötigten Speichers auf dem Heap Initialisierung des Arrays:

- bei Arrays mit primitiven Datentypen: 0, 0.0 oder false- bei Arrays mit Referenzen: null

Rückgabe einer Referenz auf das Array

Anforderung eines Speicherbereichs der Größe des Arrays mit primitiven Daten:Syntax: Beispiel:Typ[] ref = new Typ[ size ]; int[] iRef = new int[ 10 ];

Das Array enthält 10 int-Daten mit dem Wert 0. Anforderung eines Speicherbereichs der Größe des Arrays mit Referenzen:

Syntax: Beispiel:Typ[] ref = new Typ[ size ]; Bruch[] brRef = new Bruch[ 10 ];Das Array enthält 10 null-Referenzen. Es werden keine Bruch-Objekte angelegt!

Page 115: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 115

Klassen und Objekte Referenzen und dynamische Speicherverwaltung – new-Operator für Arrays

Ausführlicheres Beispiel: 4 Referenzen auf Ghost-Objekte in einem Array:Ghost[] allGhosts = new Ghost[ 4 ]; // Platz für vier Geister

for (int i = 0; i < allGhosts.length; i++) allGhosts[ i ] = new Ghost(3, 1);

for (int i = 0; i < allGhosts.length; i++) allGhosts[ i ].setX(12);

Mehrdimensionale Arrays lassen sich genauso erzeugen.

Geist 1 Geist 2 Geist 3

0x2000 0x2010 0x2020Fiktive Adressen!

0x1240 0x2000 0x2010 0x2020

0x1240

allGhosts

0x2030

Geist 4

0x2030

Page 116: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 116

Klassen und Objekte Referenzen und dynamische Speicherverwaltung – Speicherfreigabe

Was passiert mit Objekten, auf die keine Referenzen mehr existieren? Sie sind durch das eigene Programm nicht mehr erreichbar. Der interne Garbage-Collector kann sie beseitigen und wieder dem Freispeicher zuordnen. Vor der Speicherfreigabe wird die Methode protected void finalize() des zu

löschenden Objektes aufgerufen. Es kann passieren, dass die Objekte auf dem Heap bleiben, wenn genügend Speicher

vorhanden ist Zeitpunkt der Freigabe ist nicht vorhersehbar. Manueller Aufruf des Garbage-Collectors: Runtime.getRuntime().gc();

Es werden trotzdem nicht alle unerreichbaren Objekte freigegeben. Mehrfacher Aufruf, bis sich der freie Speicher nicht mehr ändert:

long freeMem = Runtime.getRuntime().freeMemory();

Page 117: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 117

Klassen und Objekte Referenzen und dynamische Speicherverwaltung – Singleton

Definition: SingletonEine Klasse, von der nur ein Objekt erzeugt werden kann.

Beispielimplementierung (nicht perfekt).public class Logger { private static Logger instance;

// Privater Konstruktor private Logger(){ }

public static Logger getInstance(){ if (instance == null) instance = new Logger(); return instance; }

public void log(String message) { // Ausgabe }}

public void test() { Logger log1 = new Logger(); // Fehler Logger log2 = Logger.getInstance(); Logger log3 = Logger.getInstance();

log2.log("Wichtige Nachricht");

// Oder kürzer Logger.getInstance().log("Nachricht");}

Page 118: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 118

Klassen und Objekte Referenzen und dynamische Speicherverwaltung – Beispiel

Implementierung einer einfach verketteten Liste doppelte Verkettung ist eine Übungsaufgabe!

Welche Klassen werden benötigt? Implementierung einiger Methoden der Klassen

Page 119: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 119

Überladen von Methoden Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 120: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 120

Überladen von Methoden

Definition: Überladen von MethodenEine Klasse besitzt zwei oder mehr Methoden mit demselben Namen und unterschiedlichen Parametertypen. Die passende Methode wird durch den Compiler ermittelt, indem er auch Typkonvertierungen durchführt.Der Rückgabetyp darf unterschiedlich sein.

Beispiel:

Klassenname

-attribut: int

+methode()+methode(wert: int)+methode(wert: String)

Page 121: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 121

Überladen von Methoden

Einsatz: Verwendung der gleichen Methode mit unterschiedlichen Parametertypen. Vorteil: Keine explizite Konvertierung der Argumente im Aufruf. Beispiel: Vereinfachter Auszug aus der bereits eingeführten Klasse GameController, die in

Pacman die Figuren steuert.

GameController

+collisionOfPacmanWith(ghost: Ghost)+collisionOfPacmanWith(cherry: Cherry)

Page 122: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 122

Überladen von Methoden

Auswahl der passenden MethodeAuswahlkriterien durch den Compiler: Die Anzahl der Parameter muss zum Aufruf passen. Alle Übergabeparameter müssen in die Parametertypen der Methode konvertierbar sein.

Beispiel:public class PrintStream { public void println(long x){} public void println(char x){}}Aufruf:PrintStream out = ...out.println(123);

Für alle Übergabeparameter wird der kleinste passende Typ gesucht. Beispiel: char int, vor char long.

Ein größerer Typ wird nie in einen kleineren Typ umgewandelt.

PrintStream

+println(x: long)+println(x: char)

int wird zu long

Page 123: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 123

Überladen von Methoden

Es wird die Methode mit der kleinsten Summe der „Konvertierungsabstände“ aller Parameter ermittelt.

Existieren mehrere Methoden mit gleichem minimalen Abstand, so wird ein Übersetzungsfehler gemeldet.

Beispiel (OK, ziemlich sinnlos):public class MyClass { public void method(long x, int y); public void method(int x, long y);}

Aufruf:MyClass cl = new MyClass();cl.method(123, 456 ); Fehler !cl.method(123L,456 );cl.method(123, 456L);

MyClass

+method(x: long, y: int)+method(x: int, y: long)

Page 124: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 124

Vererbung Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 125: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 125

Vererbung Motivation

Wie können existierende Klassen wiederverwendet werden? Welche Methoden sollte eine Klasse immer unterstützen? Welche Arten von Beziehungen können zwischen Objekten bestehen?

Page 126: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 126

Vererbung Motivation

Eigenschaften, die für eine Figur gelten, gelten eventuell auch für spezielle Figuren:

Vererbungsbeziehungen können mit der Vererbungshierarchie in der Biologie verglichen werden:

Ein Koalabär ist ein Säugetier (Mammal) ist ein Tier.

Figure

Ghost Pacman

Animal

Mammal Reptile

Kangaroo Koala Crocodile

Page 127: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 127

Vererbung Begriffe

Es gibt zwei Arten der Vererbung in Programmiersprachen: Vererbung der Spezifikation: wichtiges Konzept der objektorientierten Programmierung Vererbung der Implementierung: Mittel zur Vermeidung von Redundanzen mit einigen

konzeptuellen und praktischen Problemen Beide Techniken werden häufig unter dem Begriff der Vererbung zusammengefasst.

Page 128: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 128

Vererbung Begriffe

Definition: VererbungVererbung ist eine Programmiersprachenkonzept zur Umsetzung einer Relation zwischen einer Ober- und einer Unterklasse:Eine Klasse AbgelKlasse ist dann eine Unterklasse der Klasse BasisKlasse, wenn AbgelKlasse die Spezifikation von BasisKlasse erfüllt, umgekehrt aber BasisKlasse nicht die Spezifikation von AbgelKlasse. Die Klasse BasisKlasse ist dann eine Oberklasse von AbgelKlasse.

BasisKlasse

+operation1()

AbgelKlasse

+operation1()+operation2()

AbgelKlasse hält Vor-und Nachbedingung vonoperation1 derBasisKlasse ein.

AbgelKlasse erweitertdie eigene Spezifikationum operation2.

Page 129: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 129

Vererbung Begriffe

Die Oberklasse vererbt ihre Spezifikation (Vor- und Nachbedingungen) an die Unterklasse. Durch Unterklassen wird das Verhalten der Oberklasse nicht verändert. Durch Vererbung (Ableitung) entsteht eine Klassenhierarchie.

ist Spezialfall vonist Erweiterung von

UnterklasseSubklasseabgeleitete KlasseSpezialisierung

OberklasseSuperklasseBasisklasseGeneralisierung

ist Verallge-meinerung von

Figure

-x: int-y: int

+setX(x: int)+setY(y: int)

Ghost

-IQ: int

+getIQ(): int

Pacman

-mouthOpening: boolean+isMouthOpening(): boolean

Page 130: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 130

Vererbung Begriffe

Generalisierung und Spezialisierung – Begriffe Prozess der Klassenbildung ist ein Abstraktionsvorgang:

Spezialisierung: Aus bestehenden Klassen können spezialisierte Unterklassen (abgeleitete Klassen) gebildet werden.

Generalisierung: Gemeinsamkeiten bestehender Klassen können in gemeinsame Oberklassen (Basisklasse) verlagert werden.

Ergebnis: Klassenhierarchien aus Ober- und Unterklassen. Oberklassen: Allgemeiner und abstrakter als Unterklassen. Unterklassen: Spezieller und konkreter als Oberklassen. Der Sprachmechanismus, der dieses Konzept unterstützt, wird Vererbung genannt. Wichtig: Eine Unterklasse ist ein Untertyp von Oberklasse. Damit kann die Unterklasse überall

dort verwendet werden, wo die Oberklasse erwartet wird.

Page 131: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 131

Vererbung Begriffe

Eine Unterklasse ist ein Stellvertreter für die Oberklasse. Sie kann Methoden der Oberklasse überschreiben (umdefinieren).

Klassen Objekte

Speicherghost1

x = 1y = 4IQ = 70

pacman

x = 2y = 13mouthOpening = false

Figure

-x: int-y: int

+setX(x: int)+setY(y: int)

Ghost

-IQ: int

+getIQ(): int

Pacman

-mouthOpening: boolean

+isMouthOpening(): boolean

Page 132: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 132

Vererbung Vererbung der Spezifikation

Allgemeiner Fall: Vererbung der Spezifikation Eine Unterklasse erbt grundsätzlich die Spezifikation ihrer Oberklasse. Die Unterklasse übernimmt damit alle Verpflichtungen und Zusicherungen der Oberklasse. Häufiger wird auch der Begriff Vererbung von Schnittstellen benutzt. Vererbung der Spezifikation: Eine Unterklasse übernimmt die Verpflichtungen (Vor- und

Nachbedingungen), die sich aus der Spezifikation der Oberklasse ergeben. Vererbung ist mehr als die einfache Syntax zur Implementierung einer Schnittstelle. Prinzip der Ersetzbarkeit: Wenn die Klasse B eine abgeleitete Klasse der Klasse A ist, dann

können in einem Programm alle Objekte der Klasse A durch Objekte der Klasse B ersetzt worden sein, und es gelten trotzdem weiterhin alle zugesicherten Eigenschaften der Klasse A.

Java unterstützt dieses Konzept durch eigene Sprachmittel, C++ nicht kommt gleich genauer.

Page 133: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Spezieller Fall: Vererbung der Implementierung Anwendungsbeispiel: Es gibt eine Basisklasse, die nicht vollständig durch spezialisierte

abgeleitete Klassen abgedeckt wird. Es gibt also Objekte der Basisklasse. Beispiel (in der Basisklasse sind z.B. Beamte und Rentner):

Syntaxbeispiel:public class Angestellter extends Steuerzahler {}

Informatik 2 - Einführung in Java und UML 133

Vererbung Vererbung der Implementierung

Steuerzahler

Angestellter Selbstaendiger

Page 134: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 134

Vererbung Vererbung der Implementierung

Beispiel: Erben gesetzlicher Regelungen (aus „Praxisbuch Objektorientierung“) Gesetzliche Regelungen werden auf verschiedenen Ebenen vorgenommen. Für eine in

Karlsruhe lebende Person gilt: Die europäische Union legt rechtliche Rahmenbedingungen fest. Die Bundesrepublik Deutschland hat gesetzliche Regelungen für das Steuerrecht. Das Land Baden-Württemberg hat wiederum eigene spezielle Regelungen. Schließlich legt die Stadt Karlsruhe noch eigene Regelungen fest, zum Beispiel den so

genannten Hebesatz für die Gewerbesteuer. „Vererbung der Regelungen“

Die Karlsruher-Regelung erbt von der des Landes Baden-Württemberg. Diese wiederum erben die Regeln des Bundes. Der Bund muss die Regeln der EU akzeptieren.

Page 135: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 135

Vererbung Vererbung der Implementierung

Effekte der Vererbung der Umsetzung: Beispiel: Der allgemeine Einkommenssteuersatz wird für Karlsruhe direkt aus der

Regelung des Bundes übernommen. Eine Änderung des Einkommensteuersatzes bundesweit führt auch zu einer Änderung in

Karlsruhe. In einem bestimmten Rahmen können eigene Umsetzungen in den speziellen Fällen

erfolgen. Beispiel: Jede Kommune hat eigene Gewerbesteuerumsetzung. Die Regelungen sind hierarchisch organisiert, wobei die weiter oben liegenden Regeln jeweils

weiter unten liegende überschreiben.

Page 136: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 136

Vererbung Vererbung der Implementierung

Suche einer passenden Regelung anhand des Beispiels:

Suche eines Gesetzes durch Suchen in den Büchern „von oben nach unten“ im Stapel. Vorteil:

- Karlsruhe muss nicht den kompletten Gesetzestext der EU beinhalten.- Eine Änderung innerhalb der EU wird automatisch übernommen.- Nur kleinere Anpassungen werden lokal festgelegt Karlsruher Recht muss mit EU-

Recht übereinstimmen.

Steuerrecht Karlsruhe

Steuerrecht BW

Steuerrecht Bund

Steuerrecht EU

Suchrichtung

Page 137: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 137

Vererbung Vererbung der Implementierung

Klassenhierarchie der Regelungen:

Wie wird eine Klassenhierarchie implementiert?

Steuerrecht-EU

Steuerrecht-

Bund

Steuerrecht-BW

Steuerrecht-

Karlsruhe

Page 138: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 138

Vererbung Vererbung der Implementierung – Syntax

Beispiel: Figure als allgemeine Basisklasse für eine Figur Ghost als spezielle Figur

public class Figure { private int xPos; private int yPos;

public Figure(int xPos, int yPos) { /* ... */ } public void move(int xPos, int yPos) { /* ... */ } //...}

public class Ghost extends Figure { private boolean dangerous;

public Ghost(int xPos, int yPos, boolean dangerous) { /* ... */ } public boolean isDangerous() { /* ... */ } public void move(int xPos, int yPos) { /* ... */ } //...}

Page 139: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 139

Vererbung Vererbung der Implementierung – Konstruktorenreihenfolge

Frage: Wie funktioniert der Konstruktoraufruf in Figure jetzt, wenn ein Ghost-Objekt erzeugt wird?

Antwort: Der Konstruktor von Ghost kann Argumente an den Konstruktor der Basisklasse Figure weiterleiten.

Ein Konstruktor kann auch seine eigenen Attribute initialisieren.Vorgehensweise:

Aufruf des Basisklassenkonstruktors. Initialisierung der eigenen Attribute.

Page 140: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassenelemente werden von „oben“ nach „unten“ initialisiert: Erst wird der Konstruktor der Basisklasse aufgerufen. Dann werden die Attribute einer Klasse in der Reihenfolge ihrer Deklaration initialisiert. Abschließend wird der Konstruktor der Klasse selbst aufgerufen.

Initialisierungsreihenfolge im Ghost-Beispiel:

Informatik 2 - Einführung in Java und UML 140

Figure

-xPos: int-yPos: int

+Figure()

Ghost

-dangerous: boolean+Ghost()

Vererbung Vererbung der Implementierung – Konstruktorenreihenfolge

Initialisierungsreihenfolge

1. Attribute der Basisklasse in der Reihenfolge ihrer Deklaration

2. Konstruktor der Basisklasse

3. Attribute der abgeleiteten Klasse in der Reihenfolge ihrer Deklaration

4. Konstruktor der abgeleiteten Klasse

Page 141: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 141

Vererbung Vererbung der Implementierung – Konstruktorenreihenfolge

Beispiel: Ghostpublic Ghost(int xPos, int yPos, boolean dangerous) {

super(xPos, yPos);this.dangerous = dangerous;

}

AttributeKonstruktorBasisklasse

Page 142: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Zur Erinnerung: Vor der Freigabe wird die Methode finalize aufgerufen. Zuerst wird finalize der abgeleiteten Klasse aufgerufen. Diese Methode ruft finalize der Basisklasse auf und führt dann eigene

Aufräumarbeiten durch. Aufrufreihenfolge der finalize-Methoden im Ghost-Beispiel (sofern dort finalize

implementiert wurde):

Informatik 2 - Einführung in Java und UML 142

Figure

-xPos: int-yPos: int

#finalize()

Ghost

-dangerous: boolean#finalize()

Vererbung Vererbung der Implementierung – Freigabereihenfolge

Freigabereihenfolge

2. finalize der Basisklasse

1. finalize der abgeleiteten Klasse

ruft auf

Page 143: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 143

Vererbung Vererbung der Implementierung - Verhindern der Vererbung

Soll verhindert werden, dass von einer bestimmten Klasse geerbt wird, dann kann sie als final deklariert werden. Beispiel:public final class Game { private Cell[][] cells;

public Game() { /* ... */ }

public void run() { /* ... */ } /* ... */ }

Die Klasse String ist beispielsweise als final deklariert.

Page 144: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 144

Vererbung Vererbung der Implementierung – Klassenhierarchien

Bildung komplexer KlassenhierarchienJede abgeleitete Klasse kann die Basisklasse einer anderen Klasse sein.

public class Figure { private int xPos; private int yPos;

public Figure() { /* ... */ } public void move(int xPos, int yPos) { /* ... */ } public void print() { /* ... */ } /* ... */ }

Figure

-xPos: int-yPos: int

+Figure()

Ghost

-dangerous: boolean

+Ghost()

FlyingGhost

+FlyingGhost()

Page 145: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 145

Vererbung Vererbung der Implementierung – Klassenhierarchien

public class Ghost extends Figure { private boolean dangerous;

public void move(int xPos, int yPos) { /* ... */ } public void print() { /* ... */ } /* ... */ }

Figure

-xPos: int-yPos: int

+Figure()

Ghost

-dangerous: boolean

+Ghost()

FlyingGhost

+FlyingGhost()

Page 146: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 146

Vererbung Vererbung der Implementierung – Klassenhierarchien

public class FlyingGhost extends Ghost {

public void print() { /* ... */ } /* ... */ }

Figure

-xPos: int-yPos: int

+Figure()

Ghost

-dangerous: boolean

+Ghost()

FlyingGhost

+FlyingGhost()

Page 147: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Vererbung Vererbung der Implementierung – Klassenhierarchien

Durch den Diskriminator können Gruppen zusammengehöriger Klassen erkannt werden weitere Eigenschaften einer Vererbung gegeben werden.

Informatik 2 - Einführung in Java und UML 147

Figure

Diskriminator(optional)

Ghost Cherry Pacman

passive Figurpassive Figur

steuerbare Figur

Page 148: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Vererbung Vererbung der Implementierung – Klassenhierarchien

Der Diskriminator kann bei Gleichheit auch so notiert werden:

Informatik 2 - Einführung in Java und UML 148

gilt für beideKlassen

Figure

Ghost Cherry Pacman

passive Figur steuerbare Figur

Page 149: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Vererbung Vererbung der Implementierung – Klassenhierarchien

Mehrfachvererbung einer Implementierung: Eine Klasse hat mehr als eine direkte Basisklasse (in Java nicht möglich).

Informatik 2 - Einführung in Java und UML 149

HSAngehoeriger

Student Dozent

Tutor

Page 150: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 150

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

Neues Zugriffsrecht: protected für Vererbung räumt einer abgeleiteten Klasse mehr Rechte als einer anderen Klasse ein.

Eine abgeleitete Klasse kann alle public- oder protected-Methoden aller seiner Basisklassen aufrufen. alle public- oder protected-Attribute aller seiner Basisklassen lesen und

beschreiben. nicht auf die privaten Methoden oder privaten Attribute der Basisklassen zugreifen.

Wird eine abgeleitete Klasse in einem Programm verwendet, so kann nur auf die public-Methoden oder Attribute dieser Klasse sowie deren Oberklassen zugegriffen werden.Beispiel:Ghost ghost = new Ghost(3, 2, true);ghost.move(3, 1); // OKboolean dangerous = ghost.dangerous; // Fehler, privat

Page 151: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 151

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

Szenario:

public class A { public int i1; protected int i2; private int i3; int i4;

}

class B extends A {

}

class C {

}

class D extends A {

}

class E {

}

hska.iwii.my hska.iwii.p1 hska.iwii.p2

class F {

}

//code

//code

//code

//code

//code //code

Page 152: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 152

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

public int i1 ist in allen Klassen und Paketen sichtbar.

public class A { public int i1; protected int i2; private int i3; int i4;

}

class B extends A {

}

class C {

}

class D extends A {

}

class E {

}

class F {

}

//code

//code //code

//code //code//code

hska.iwii.my hska.iwii.p1 hska.iwii.p2

Page 153: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 153

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

protected int i2 ist in Unterklassen und im eigenen Paket sichtbar.

public class A { public int i1; protected int i2; private int i3; int i4;

}

class B extends A {

}

class C {

}

class D extends A {

}

class E {

}

class F {

}

//code

//code

//code

//code

//code //code

hska.iwii.my hska.iwii.p1 hska.iwii.p2

Page 154: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 154

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

private int i3 ist nur in der eigenen Klasse sichtbar.

public class A { public int i1; protected int i2; private int i3; int i4;

}

class B extends A {

}

class C {

}

class D extends A {

}

class E {

}

class F {

}

//code

//code

//code

//code

//code //code

hska.iwii.my hska.iwii.p1 hska.iwii.p2

Page 155: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 155

Vererbung Vererbung der Implementierung – Rechte bei Attribut- oder Methodenzugriffen

int i4 ist im eigenen Package sichtbar.

public class A { public int i1; protected int i2; private int i3; int i4;

}

class B extends A {

}

class C {

}

class D extends A {

}

class E {

}

class F {

}

//code

//code

//code

//code

//code //code

hska.iwii.my hska.iwii.p1 hska.iwii.p2

Page 156: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 156

Überschreiben von Methoden Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 157: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 157

Überschreiben von Methoden Grundlagen

Idee: Eine abgeleitete Klasse besitzt eine Methode mit demselben Namen und derselben Signatur wie die Basisklasse.

Ein häufiges Problem beim Prinzip der Ersetzbarkeit: Eine Basisklassenreferenz verweist auf ein Objekt einer abgeleiteten Klasse. Wie kann festgestellt werden, welcher Klasse das Objekt angehört wichtig für den

Aufruf der korrekten Methode?

Basisklasse

+print()

AbgeleiteteKlasse

+print()

Page 158: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 158

Überschreiben von Methoden Grundlagen

Definition: Überschreiben (von Methoden) Wenn eine abgeleitete Klasse eine Methode implementiert, für die es bereits in einer

Basisklasse eine Methode gibt, so überschreibt die abgeleitete Klasse die Methode der Basisklasse.

Wird die Operation auf einem Exemplar der abgeleiteten Klasse aufgerufen, so wird die überschriebene Implementierung der Methode aufgerufen.

Das ist unabhängig davon, welchen Typ die Referenz hat, über die das Objekt angesprochen wird.

Entscheidend ist der Typ des Objekts selbst, nicht der Typ der Variablen.

Page 159: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 159

Überschreiben von Methoden Grundlagen

Aufruf der neuen Methode print.public class Figure { public void print() { System.out.println("Figure"); }}

public class Ghost extends Figure { private boolean dangerous; @Override public void print() { System.out.println("Ghost"); }}

// …private int test() { Ghost ghost = new Ghost(3, 2, true); Figure figure = ghost; ghost.print(); figure.print(); // ...

Figure

-xPos: int-yPos: int

+print()

Ghost

-dangerous: boolean+print()

Ausgabe:GhostGhost

Page 160: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 160

Überschreiben von Methoden Verhalten

Verhalten Aufruf der Methode der abgeleiteten Klasse (auch, wenn die Methode über eine

Basisklassenreferenz aufgerufen wird). Vorteil: Code, der die Methoden aufruft, bleibt unverändert, selbst wenn Klassen

hinzukommen oder sich Klassen ändern. Verhalten

Alle Methoden, die nicht als final deklariert werden, können überschrieben werden. Signatur und Name der Methode müssen in Basisklasse und abgeleiteter Klasse identisch

sein. Überschreibende Methoden sollten mit der Annotation @Override versehen werden. Dann

kann der Compiler prüfen, ob diese Methode wirklich eine andere überschreibt:public class Ghost extends Figure { @Override public void print() { System.out.println("Ghost"); }}

Page 161: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 161

Überschreiben von Methoden Verhalten

Beispiel für eine Methode, die nicht überschrieben werden darf:public class Figure { public final void print() { System.out.println("Figure"); }}

Page 162: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 162

Überschreiben von Methoden Manueller Einfluss

Manueller Einfluss auf das Überschreiben Umgehung der automatischen Methodenauswahl, expliziter Aufruf einer Methode der

Basisklasse: super.methode(Parameter);Beispiel:public class Figure { // ... public void move(int xPos, int yPos) { // ... }}

public class Ghost extends Figure { // ... @Override public void move(int xPos, int yPos) { super.move(xPos, yPos); // z.B. Neuzeichnen }}

Figure

-xPos: int-yPos: int

+move(xPos: int, yPos: int)

Ghost

-dangerous: boolean+move(xPos: int, yPos: int)

Page 163: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 163

Überschreiben von Methoden Konstruktoren

Konstruktoren und Überschreiben Der Konstruktor der Basisklasse wird vor dem Konstruktor der abgeleiteten Klasse ausgeführt. Aufruf einer polymorphen Methode im Konstruktor der Basisklasse:

Im Gegensatz zu C++: Aufruf der überschriebenen Methode Achtung: Die abgeleitete Klasse ist noch gar nicht initialisiert!! Konsequenz: Konstruktoren sollten nur private oder finale Methoden aufrufen.

public class Base { private Bruch br; public Base() { br = new Bruch(); init(); } public void init() { br.setZaehler(42); }}

public class Derived extends Base { private MathVector mv; public Derived() { mv = new MathVector(3,true); init(); } @Override public void init() { mv.setValue(0, 66); }}

janein

Base

+Base()+init()

Derived

+Derived()+init()

Page 164: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 164

Überschreiben von Methoden Hinweise

Hinweise zum Umgang mit dem ÜberschreibenErmittlung der „richtigen“ Methode: Zur Übersetzungszeit (early binding, statische Bindung):

Der Aufruf kann vom Compiler direkt in Bytecode umgesetzt werden, da die Methode jederzeit bekannt ist.

nur für Methoden möglich, die als final oder private deklariert sind Zur Laufzeit (late binding, dynamische Bindung):

Alle Methoden, die nicht final, nicht privat und nicht statisch sind Polymorphismus. Das Objekt findet selbst heraus, welche Methode aufgerufen werden soll

geringer Mehraufwand beim Methodenaufruf Die überschreibende Methode der abgeleiteten Klasse darf die Zugriffsrechte der

Methode der Basisklasse nicht einschränken.

Page 165: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 165

Überschreiben von Methoden Hinweise

Hinweise zum Design „Normale“ Methoden:

Alle Methoden einer Klasse, die überschrieben werden dürfen, sollten nicht final sein. final sollte nur aus Design- nicht aus Geschwindigkeitsgründen hinzugefügt werden.

Finale Methoden: Methoden, die nicht überschrieben werden dürfen, sollten als final deklariert werden.

Page 166: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 166

Überschreiben von Methoden Regeln

Wiederholung: Prinzip der Ersetzbarkeit Wenn die Klasse Abgel eine abgeleitete Klasse der Klasse Basis ist, dann können in einem

Programm alle Objekte der Klasse Basis durch Objekte der Klasse Abgel ersetzt worden sein, und es gelten trotzdem weiterhin alle zugesicherten Eigenschaften der Klasse Basis.

Der für die Basisklasse geschlossene Kontrakt mit Bezug auf Vorbedingungen, Nachbedingungen und Invarianten gilt also auch dann weiter, wenn Objekte der Basisklasse durch Objekte der abgeleiteten Klasse ersetzt werden.

Beim Überschreiben von Methoden gilt also: Abgeleitete Klassen dürfen zwar mehr anbieten, aber nicht mehr verlangen als Exemplare ihrer Basisklassen.

Page 167: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 167

Überschreiben von Methoden Regeln

Liskovsches SubstitutionsprinzipFormulierung 1993 von Barbara Liskov und Jeannette Wing: Basisklasse Basis b ist ein Objekt von Basis. Abgeleitete Klasse Abgeleitet,

die von Basis erbt a ist ein Objekt von Abgeleitet. Es gilt:

Sei q(b) eine beweisbare Eigenschaft von Objekten b des Typs Basis. Dann soll q(a) für Objekte a des Typs Abgeleitet wahr sein.

Beispiele kommen gleich!

Besser verständlich als „ist-ein“-Beziehung.

Basis

Abgeleitet

Page 168: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 168

Überschreiben von Methoden Regeln

Konsequenzen für die Vorbedingungen, Nachbedingungen und Invarianten einer abgeleiteten Klasse:

Schwächere Vorbedingungen:- Eine abgeleitete Klasse kann die Vorbedingungen für eine Operation, die durch die

Basisklasse definiert wird, einhalten oder abschwächen. Sie darf die Vorbedingungen aber nicht verschärfen.

- Falls eine abgeleitete Klasse die Vorbedingungen verschärfen würde, würde damit ohne Absprache mit den Partnern von diesen mehr verlangt als vorher.

- Erlaubte und verbotene Maßnahmen (unvollständig):Der Wertebereich der Übergabeparameter wird erweitert.Eine nicht öffentliche Methode wird öffentlich überschrieben.Der Wertebereich der Übergabeparameter wird verkleinert.Der Übergabeparameter wird von einem Objekt der Basisklasse auf ein Objekt der abgeleiteten Klasse eingeschränkt.

Page 169: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 169

Überschreiben von Methoden Regeln

Stärkere Nachbedingungen:- Eine abgeleitete Klasse kann die Nachbedingungen für eine Operation, die durch eine

Oberklasse definiert werden, einhalten oder einschränken. Sie darf die Nachbedingungen aber nicht lockern.

- Falls eine abgeleitete Klasse die Nachbedingungen lockern würde, würde diesen damit wieder ohne Absprache mit den Partnern des Kontrakts mehr geboten als vorher.

- Erlaubte und verbotene Maßnahmen (unvollständig):Der Wertebereich der Rückgabeergebnisse wird eingeschränkt.Der Rückgabetyp ist ein Objekt der abgeleiteten Klasse A (A erbt von B), während die Methode der Basisklasse ein Objekt einer Basisklasse B zurückgibt.Der Wertebereich der Rückgabeergebnisse wird erweitert.Der Rückgabetyp ist ein Objekt der Basisklasse B, während die Methode der Basisklasse ein Objekt einer abgeleiteten Klasse A (A erbt von B) zurückgibt.

Page 170: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 170

Überschreiben von Methoden Regeln

Invarianten:- Eine abgeleitete Klasse muss dafür sorgen, dass die für die Basisklasse definierten

Invarianten immer gelten. Sie darf die Invarianten verschärfen.- Die Partner des Kontrakts müssen sich auf die zugesicherten Invarianten verlassen

können.- Eine Verhaltensänderung darf eintreten.

Ergebnis: Design by Contract

Page 171: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 171

Überschreiben von Methoden Regeln

Beispiel für die Verletzung der Ersetzbarkeit:

Figure

+display()

Rectangle

+display()+scaleX(factor: double)+scaleY(factor: double)

context Rectangle::scaleX(factor: float)

pre: factor > 0

post: (lengthX = lengthX@pre * factor and lengthY = lengthY@pre)

-lengthX: int-lengthY: int

Square

context Square

inv: lengthX = lengthY

Ersetzbarkeit verletzt:Neue Einschränkungder Längen in derInvariante desQuadrates!

Page 172: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 172

Überschreiben von Methoden Regeln

Beispiel für die Einhaltung der Ersetzbarkeit:

Account

+withdraw(amount: int)+payin(amount: int)+getBalance(): int

CreditAccount

+withdraw(amount: int)+changeLimit(limit: int)

context Account::withdraw

pre: amount > 0 and amount <= balance

post: balance = balance@pre - amount

-creditLimit: int

Nachbedingung wurde nicht gelockert, Vorbedingung gelockert ok.

-balance: int

context CreditAccount::withdraw

pre: amount > 0 and amount <= (balance + creditLimit)

post: balance = balance@pre - amount

Page 173: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 173

Überschreiben von Methoden Regeln

Implementierung des Kontobeispiels:public class Account { private int balance = 0;

public int getBalance() { return balance; }

    public void withdraw(int amount) {    assert amount > 0

&& amount <= balance;

    balance -= amount;  }

  public void payin(int amount) {    balance += amount;  }}

public class CreditAccount extends

Account { private int creditLimit;

public CreditAccount(int limit) { creditLimit = limit; }

@Override     public void withdraw(int amount) {

    assert amount > 0 && amount <= (balance + creditLimit);

    balance -= amount;  }

  public void changeLimit(int limit) {    creditLimit = limit;  }}

Page 174: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 174

Überschreiben von Methoden Regeln

Verwendung des Kontobeispiels:CreditAccount account1 = new CreditAccount(10000);Account account2 = new Account();

// Abhebenbank.withdraw(account1);bank.withdraw(account2);

// Methode zum Abheben eines Festbetrags// account verweist auf Account oder CreditAccountpublic void withdraw(Account accountPtr) { if (accountPtr.getBalance() >= 200) accountPtr.withdraw(200);}

Wichtig: In der Methode withdraw sind Vor- und Nachbedingung sowie Invariante nur anhand der Klasse Account erkennbar!

Page 175: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 175

Überschreiben von Methoden Regeln

Beispiel für die Verletzung der Ersetzbarkeit (Einschränkung der Vorbedingung):

Account

+withdraw(amount: int)+payin(amount: int)+getBalance(): int+transfer(amount: int, dest: Account)+setCreditLimit(limit: int)

DepositAccount

+transfer(amount: int, dest: Account)+setCreditLimit(limit: int)

context Account::transfer

pre: amount > 0 and amount <= balance + creditLimit

post: (balance = balance@pre – amount and dest.balance = dest.balance@pre + amount)

Die Überweisung von einem Sparkonto wird verboten Einschränkungder Vorbedingung!

-balance: int-creditLimit: int

context DepositAccount::transfer

pre: false

Page 176: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 176

Überschreiben von Methoden Regeln

Implementierung des Kontobeispiels (unvollständig):public class Account { private int balance = 0; private int creditLimit = 0;

public int getBalance() { return balance; } public void transfer(int amount, Account dest) {

    assert amount > 0 && amount <= (balance + creditLimit));    balance -= amount; dest.payin(amount);  }

  public void payin(int amount) { assert amount > 0;    balance += amount;  }}

public class DepositAccount extends Account {

@Override  public void transfer(int amount, Account dest) {    assert false;

}

}

Page 177: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 177

Überschreiben von Methoden Regeln

Verwendung des Kontobeispiels:DepositAccount account1 = new DepositAccount();Account account2 = new Account();

// Überweisenbank.transfer(account1, account2);bank.transfer(account2, account1);

// Methode zum Überweisen eines Festbetragspublic void transfer(Account dest, Account source) { if (source.getBalance() + source.getCreditLimit() >= 200) source.transfer(200, dest);}

Wichtig: In der Methode transfer berücksichtigt die Vorbedingung der Klasse Account. DepositAccount schränkt diese aber ein Methode transfer kann nicht richtig funktionieren.

Page 178: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 178

Überschreiben von Methoden Regeln

Problem: Die Kontraktverletzungen werden erst zur Laufzeit entdeckt vollständige Test erforderlich.

Lösung: Spracherweiterungen, die eine Spezifikation der Kontrakte erlauben Problem: Prüfungen auf Kontrakteinhaltung müssen manuell in den Code verteilt werden

sehr viel Arbeit. Lösung: AOP (Aspect Oriented Programming) kommt später

Page 179: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 179

Überschreiben von Methoden Regeln

Wie können Kontrakte angegeben werden? in UML mit OCL im Quelltext mit Assertions (auch mit Hilfe von AOP) Es gibt Erweiterungen objektorientierter Sprachen um Constraints, Auswahl:

jContractor (http://jcontractor.sourceforge.net/),C4J (http://c4j.sourceforge.net/),COFOJA (http://code.google.com/p/cofoja)

Wie sieht es bei Schnittstellen oder abstrakten Klassen aus? Dort gibt es keine Implementierung!

in UML mit OCL spezifizieren im Quelltext dokumentieren Constraint-Erweiterung verwenden

Page 180: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 180

Überschreiben von Methoden Kovarianz und Kontravarianz

Genauerer Blick auf die Vererbung bei Methodenparametern und Rückgabetypen Kovariante Rückgabetypen in der clone-Methode: Der Rückgabetyp in der abgeleiteten

Klasse erbt vom Rückgabetyp der Basisklasse

Einschränkung der Nachbedingung in dieser Form ist erlaubt. Java unterstützt seit Version 5 kovariante Rückgabetypen. C++ hat kovariante Rückgabetypen im Standard definiert. Allerdings unterstützen nicht

alle Compiler dieses Sprachmittel.

Figure

+clone(): Figure

Ghost

+clone(): Ghost

-x: int-y: int

Die Klasse T2 ist der Klasse T1 kovariant, wenn alle Objekte von T2 gleichzeitigObjekte von T1 sind.Einfacher gesagt: T2 muss entweder T1 oder eine abgeleitete Klasse sein.

Page 181: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 181

Überschreiben von Methoden Kovarianz und Kontravarianz

Kovariante Übergabetypen in der set-Methode: Der Übergabegabetyp in der abgeleiteten Klasse erbt vom Übergabegabetyp der Basisklasse

Die Einschränkung der Vorbedingung ist nicht erlaubt. Ausweg: In Java und C++ wird die Methode set in Figure gar nicht überschrieben, sie

wird überladen! Schlussfolgerung: Die Übergabetypen sind nicht kovariant.

Figure

+set(f: Figure)

Ghost

+set(g: Ghost)

-x: int-y: int

Page 182: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 182

Überschreiben von Methoden Kovarianz und Kontravarianz

Kontravariante Übergabetypen in der set-Methode: Der Übergabegabetyp in der abgeleiteten Klasse ist Basisklasse des Übergabetyps der Basisklasse

Aufweichung der Vorbedingung ist erlaubt. Kontravariante Übergabetypen sind erlaubt.

Kontravariante Rückgabetypen sind nicht erlaubt.

Figure

+set(g: Ghost)

Ghost

+set(f: Figure)

-x: int-y: int

Die Klasse T2 ist der Klasse T1 kontravariant, wenn alle Objekte von T1 gleichzeitigObjekte von T2 sind.Einfacher gesagt: T1 muss entweder T2 oder seine abgeleitete Klasse sein.

Page 183: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 183

Vererbung Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 184: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 184

Vererbung Vererbung der Implementierung (abstrakte Basisklasse)

Spezialfall der Vererbung: Abstrakte Basisklasse Idee: Es gibt keine Objekte der Oberklasse. Alle Objekte der Basisklasse müssen durch

Unterklassenobjekte repräsentiert werden. Beispiel: Ein Konto ist entweder ein Girokonto oder ein Sparkonto. Es muss eines von beiden sein, kann aber nicht in beiden Klassen gleichzeitig sein. Pacman-Beispiel: Es gibt keine Objekte der Basisklasse Figure.

kursivFigure

Ghost Pacman

Page 185: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 185

Vererbung Vererbung der Implementierung (abstrakte Basisklasse)

Klassen werden mit dem Schlüsselwort abstract als abstrakt markiert, um zu verhindern, dass ein Objekt solcher Klasse erzeugt wird.

Beispiel: Figure, von dem keine Objekte erzeugt werden dürfen.public abstract class Figure { private int xPos; private int yPos;

public void handleCollisionWith(Figure other) { // ... }}

public class Pacman extends Figure { private boolean mouthOpening;

@Override public void handleCollisionWith(Figure other) { // ... } // ...}

Überschreiben bzw.implementieren der Methode

Page 186: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 186

Vererbung Vererbung der Implementierung (abstrakte Basisklasse)

Auch Methoden können abstrakt sein: Die Basisklasse kann z.B. keine sinnvolle gemeinsame Implementierung anbieten. Die abgeleiteten Klassen müssen die Methoden dann implementieren. Ein Klasse mit mindestens einer abstrakten Methode ist abstrakt.

Beispiel: Figure ohne Implementierung des Zeichnenspublic abstract class Figure { private boolean dead;

public abstract void paint(Canvas panel); // ...}

keine Implementierung

Page 187: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 187

Vererbung Vererbung der Spezifikation (Schnittstellen)

Für die Vererbung einer Spezifikation gibt es in Java Schnittstellen (interface). Es werden Methodensignaturen vorgegeben, die eine erbende Klasse implementiert. Beispiel: Schnittstelle Runnable aus dem JDK

public interface Runnable { void run();

} Alle Methoden sind public (nicht angegeben). Alle Attribute sind public, static und final

(nicht angegeben).

Implementierung einer Schnittstelle:public class Figure implements Runnable { @Override public void run() { /* ... */ }

} Eine Klasse darf beliebig viele Schnittstellen direkt implementieren (die Schnittstellen werden

mit Kommata getrennt aufgeführt).

<<interface>>Runnable

+run()

Figure

-xPos: int-yPos: int

+run()

Stereotyp<<interface>>

Page 188: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 188

Vererbung Vererbung der Spezifikation (Schnittstellen)

Was passiert, wenn eine Schnittstelle um zusätzliche Methoden erweitert werden soll? Alle erbenden Klassen müssten angepasst werden schwer umsetzbar, wenn weltweit

tausende Projekte die Schnittstellen verwenden! Problem wurde bei der Erweiterung der Collections-Klassen in Java 8 behoben. Lösung: Schnittstellen dürfen Methoden Standard-Implementierungen geben:

public interface MyInterface { void make(); default int makeFourtyTwo() { return 42; }

} Wenn die erbende Klasse die Methode nicht implementiert, dann wird die Implementierung

der Schnittstelle verwendet. Tipp: Wirklich nur für eine spätere Erweiterung von Schnittstellen verwenden!

Page 189: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 189

Vererbung Vererbung der Spezifikation (Schnittstellen)

Schnittstellen dürfen auch statische Methoden besitzen. Diese müssen eine Standard-Implementierung enthalten.public interface MyInterface { void make(); static MyInterface getInstance() { return new MyClass(); }

} Sinnvoll für sogenannte Fabrik-Methoden (Methoden erzeugen Objekte einer Klasse)

Einsatz kommt später im Datenstruktur-Kapitel.

Page 190: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Vererbung Vererbung der Spezifikation (Schnittstellen)

Alternative Darstellung mit Ball-Symbol (die Klasse Figure implementiert die Schnittstelle Runnable):

Algorithmen und Datenstrukturen operieren häufig nur auf Schnittstellen: Klassendiagramme einer Beziehung genau wie bei einer Abhängigkeit zwischen Klassen

notwendig Hier: Klasse benötigt eine Schnittstelle

Informatik 2 - Einführung in Java und UML 190

Figure

+run() Runnable Schnittstellenname

implementierteSchnittstelle

ControllerbenötigteSchnittstelle

<<interface>>Runnable

+run()

<<use>>

Page 191: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Vererbung Vererbung der Spezifikation (Schnittstellen)

Alternative Darstellung mit dem Ball-Symbol:

Gemeinsame Darstellung: Schnittstelle, implementierende Klasse und Klasse, die die Schnittstelle benötigt, in der Ball-Darstellung:

Implementierung:public class Controller { private Runnable[] elements; // ...}

Informatik 2 - Einführung in Java und UML 191

ControllerbenötigteSchnittstelle

Runnable Schnittstellenname

Controller

Runnable

Figure

+run()

Page 192: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 192

Vererbung Beispiel: „Pacman“

Ziel: Klassenhierarchie für das Zeichenprogramm oder Pacman-Figuren Die Algorithmen des Programms sollen auch mit noch „unbekannten“ Figuren funktionieren

Erweiterbarkeit!

Page 193: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 193

Generische Klassen Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 194: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 194

Generische Klassen

Definition: Generische KlasseEine generische Klasse ist eine mit formalen generischen Parametern versehene Schablone. Erst durch die Verwendung der Klasse werden die Parameter durch konkrete Klassen ersetzt. So kann zur Übersetzungszeit eine höhere Typsicherheit sichergestellt werden.

Darstellung mit UML:

Parameteraufbau: Parameter-Name[:Parameter-Typ][=Vorgabewert] Parameter-Name: Name des Platzhalters Parameter-Typ: Optionale Klasse des Parameters. Ist kein Typ angegeben, kann jede

beliebige Klasse class verwendet werden. Vorgabewert: Standardwert, falls die Typangabe fehlt

TemplateKlasseT: class Parametertyp

Parametername

Page 195: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 195

Generische Klassen Vektor (Version 3)

Vektor als generische Klasse:public class Vector<E> { private E[] values;

@SuppressWarnings("unchecked") public Vector(int size, E initValue) { values = (E[]) new Object[ size ]; for (int i = 0; i < size; ++i) { values[ i ] = initValue; } }

public void setValue(int index, E value) { values[ index ] = value; }

public E getValue(int index) { return values[ index ]; }}

Vector

- values: E[*] {bag}

+ Vector(size: int, initValue: E)+ setValue(index: int, value: E)+ getValue(index: int): E

E: class

Page 196: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 196

Generische Klassen

Anmerkungen: public class Vector<E>: <E> ist der Platzhalter für eine Klasse. Der Platzhalter steht immer für den Namen einer Klasse oder Schnittstelle:

- Primitive Datentypen werden nicht unterstützt.- Intern speichert die Klasse Referenzen vom Typ Object ab.- Der Platzhalter dient zum typsicheren Zugriff, der zur Übersetzungszeit geprüft

werden kann.- Der Platzhaltertyp kann fast wie ein normaler Datentyp innerhalb der Klasse

verwendet werden. Ausnahmen: Objekterzeugung, Arrays Der cast-Operator im Konstruktor ist nicht geprüft. Deshalb wird die Warnung des

Compilers mit @SuppressWarnings("unchecked") unterdrückt. In Java können keine Arrays mit generischen Typen angelegt werden. Deshalb erzeugt der

Vektor Object-Arrays kommt noch genauer. Es dürfen mehrere Platzhalter verwendet werden. Beispiel:public class HashMap<K,V> { /* … */ }

Page 197: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 197

Generische Klassen

Eine konkrete Instanz einer generischen Klasse wird durch die folgende Schreibweise erzeugt: Klasse<Typ>

Beispiel:Vector<Double> vector1 = new Vector<>(3, 0.0);

Beispiel (der Compiler stellt sicher, dass die rot markierten Elemente vom Typ Double bzw. double sind):Vector<Double> v1 = new Vector<>(3, 0.0);v1.setValue(0, 2.0);double value = v1.getValue();System.out.println(value);

Beispiel ohne generische Klasse (der Compiler kann keine Typprüfung vornehmen):Vector v1 = new Vector(3, 0.0);v1.setValue(0, 2.0);Double value = (Double) v1.getValue();System.out.println(value);Falsche Werte (z.B. String) werden zur Laufzeit bemerkt (ClassCastException).

Kann anhand des Typs der Referenz erkannt werden.

Page 198: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 198

Generische Klassen Umsetzung in der virtuellen Maschine

Generische Klassen wurden erst mit Java 5 eingeführt. Ziel war es, den Bytecode zu Java 1.4 kompatibel zu halten. Wie lassen sich generische Klassen implementieren?

heterogen: Für jeden Typparameter wird eine neue Klasse erzeugt (C++-Ansatz). homogen: Es wird nur eine Klasse erzeugt. Der Typparameter wird durch die oberste

Basisklasse Object ersetzt. Die Typparameter dienen nur zur Prüfung während der Übersetzungszeit (Java-Ansatz).

Der Compiler löscht also die Typ-Informationen („type erasure“): Der Bytecode bleibt kompatibel zu Java 1.4. Die generischen Typen existieren nicht mehr zur Laufzeit führt zu Problemen:

Vector<Double> v1 = new Vector<>();if (v1 instanceof Vector<Double>) // Compilerfehler, da Vector<Double> zur // Laufzeit nicht existiert!Korrekt wäre:Vector<Double> v1 = new Vector<>();if (v1 instanceof Vector) // Vector existiert

Page 199: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 199

Generische Klassen Umsetzung in der virtuellen Maschine

Damit sind die Klassen trotz unterschiedlicher Typparameter identisch:Vector<Double> v1 = new Vector<>();Vector<String> v2 = new Vector<>();if (v1.getClass() == v2.getClass()) // true

Generische Klassen lassen sich auch ohne Typparameter verwenden („raw type“):Vector v1 = new Vector<Double>();Vector v2 = new Vector();Die Verwendung führt aber z.B. bei setValue zu einer Compiler-Warnung.

Page 200: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 200

Generische Klassen Umsetzung in der virtuellen Maschine

Beispiel für die Umsetzung anhand des Vektors (Ausschnitt):

public class Vector<E> { private E[] values;

// ...

public void setValue(int ind, E v) { values[ ind ] = v; }

public E getValue(int ind) { return values[ ind ]; }}

Vector<String> names = new Vector<>();names.setValue(0, "Vogelsang");String name = names.getValue(0);

Definition im Quelltext

Verwendung im Quelltext

public class Vector { private Object[] values;

// ...

public void setValue(int ind, Object v) { values[ ind ] = v; }

public Object getValue(int ind) { return values[ ind ]; }}

Definition zur Laufzeit („fiktiv“)

Vector names = new Vector();names.setValue(0, "Vogelsang");String name = (String) names.getValue(0);

Verwendung zur Laufzeit („fiktiv“)

Page 201: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 201

Generische Klassen Arrays

Arrays mit generischen Typen haben einige Besonderheiten: Die Deklaration ist problemlos möglich:

private ArrayList<String>[] al; Aber eine Initialisierung klappt nicht intuitiv:

private ArrayList<String>[] al = new ArrayList<>[ 10 ]; // Compilerfehler

Lösungen: Verwendung des Platzhalters ?:

private ArrayList<String>[] al = (ArrayList<String>[]) new ArrayList<?>[ 10 ];

Erstellen einer Klasse für den Inhalt der Arrayzellen:public class MyList extends ArrayList<String> { // notwendige Konstruktoren}private MyList[] al = new MyList[ 10 ];

Page 202: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Generische Klassen Schnittstellen

Auch Schnittstellen können generisch sein:

Informatik 2 - Einführung in Java und UML 202

<<interface>>Comparable

+compareTo(o: T): int

String

+compareTo(o: String): int

Integer

+compareTo(o: Integer): int

Schnittstellen-implementierung

T: class

Page 203: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 203

Generische Klassen Schnittstellen

Schnittstelle Comparable aus dem JDK:public interface Comparable<E> { int compareTo(E other);}

Implementierung der Schnittstelle:public class String implements Comparable<String> { @Override public int compareTo(String other) { // ... }}

Einsatzbeispiel für die Schnittstelle: Ein Sortieralgorithmus soll beliebige Arrays sortieren können. Wie soll dieser Algorithmus wissen, welche Daten größer und welche kleiner sind? Lösung: Er fragt z.B. die Daten selbst!

Page 204: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 204

Generische Klassen Schnittstellen

Variante 1: Daten müssen die Schnittstelle Comparable implementieren.public class Customer implements Comparable<Customer> { // ... private int number; @Override public int compareTo(Customer other) { return number – other.number; }}

Jetzt kann der existierende Sortieralgorithmus verwendet werden:ArrayList<Customer> customers = new ArrayList<>();// ...Collections.sort(customers);

Problem: Was passiert, wenn nach unterschiedlichen Kriterien sortiert werden soll? Lösung: Der Vergleich hat nichts in der Klasse Customer zu suchen. Er wird als Argument an

den Algorithmus übergeben.

Hinweis: Wenn compareTo implementiert wird, sollte auch equals überschrieben werden (kommt noch…).

Page 205: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 205

Generische Klassen Schnittstellen

Variante 2: Separater „Vergleicher“, der die generische Schnittstelle Comparator<T> implementiert.public class Customer { // ... private int number; // Getter und Setter}

Vergleicher für zwei Kundenobjekte:public class CustomerNumberComparator implements Comparator<Customer> { @Override public int compare(Customer c1, Customer c2) { return c1.getNumber() – c2.getNumber(); }}

Jetzt kann der existierende Sortieralgorithmus verwendet werden:ArrayList<Customer> customers = new ArrayList<>();// ...Collections.sort(customers, new CustomerNumberComparator());

Es wird eine „Funktion“ in einem Objekt gekapselt geht noch eleganter kommt später…

Page 206: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 206

Generische Methoden

„Normale“ (nicht-generische) und generische Klassen dürfen generische Methoden besitzen. Das wird häufig bei Hilfsklassen mit statischen Methoden eingesetzt: Beispiel: Methode asArrayList erzeugt aus einer variablen Anzahl Übergabewerte eine

ArrayList (angelehnt an Klasse Arrays aus dem SDK)public class Arrays { @SafeVarargs public static <T> ArrayList<T> asArrayList(T... a) { ArrayList<T> result = new ArrayList<>(a.length); for (int i = 0; i < a.length; ++i) { result.add(a[ i ]); } return result; }}

Syntax: Zugriffsrecht <T> Rückgabetyp Methodenname(Parameter)

Page 207: Informatik 2 Einführung in Java und UML

Holger Vogelsang 207

Generische Klassen Einschränkungen der Parametertypen

Die Typparameter lassen sich einschränken: Basisklasse: Der Parametertyp muss von einer bestimmten oder mehreren Basisklassen

erben. Schnittstellen: Der Parametertyp muss eine bestimmte oder mehrere Schnittstellen

implementieren. Beispiel, in dem der Vektor nur mit Klassen, die von Number erben, verwendet werden darf

(weil der Vektor z.B. Zahlenoperationen durchführt), Vektor Version 4:public class Vector<E extends Number> { private Number[] values; public double getSum() { // Summe alle Werte ermitteln double sum = 0.0; for (int i = 0; i < values.length; ++i) { sum += values[ i ].doubleValue(); } return sum; } // ...}

Informatik 2 - Einführung in Java und UML

Page 208: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 208

Generische Klassen Einschränkungen der Parametertypen

Es können auch mehrere Einschränkungen vorhanden sein. Bespiel: Der Typparameter des Vektors muss von Number erben und Cloneable

implementieren:public class Vector<E extends Number & Cloneable>

Syntax bei mehr als zwei Einschränkungen:public class Klasse<E extends C1 & C2 & C3>

Achtung bei Vererbung:Vector<Object> ist keine Basisklasse von Vector<Double>!Vector<Object> v1 = new Vector<Double>(); // Compilerfehler!Ansonsten ließe sich z.B. ein String in dem Vektor speichern.Die Methodepublic void dump(Vector<Object> v1)darf nicht mit einem Vector<Double> aufgerufen werden.

Page 209: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 209

Generische Klassen Parametertypen und Vererbung

Ausweg: Wildcards erlauben es, einen Typ unbestimmt zu lassen. Beispiel:public void dump(Vector<?> v1) ? ist ein unbekannter Typ, nicht Object. Die Methode dump darf jetzt mit jedem beliebigen Typparameter verwendet werden.

Wildcards unterstützen auch Typeinschränkungen („upper bound wildcards“): public void dump(Vector<? extends Number> v1) Es können nur Vektoren übergeben werden, deren Inhalt von Number erbt.

Einschränkung des Typparameters „nach unten“: public void dump(Vector<? super MyClass> v1) Es können nur Vektoren übergeben werden, deren Inhalt MyClass oder seine

Basisklassen bzw. Schnittstellen sind. Klassen, die von MyClass erben, sind nicht erlaubt.

Page 210: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 210

Aufzähltypen Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 211: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 211

Aufzähltypen Einführung

Ein Aufzähltyp ist eine spezielle Klasse, von der benannte Objekte erzeugt werden.Beispiel für die Bewegungsrichtungen von Figuren in Pacman:public enum Direction { NONE, UP, DOWN, LEFT, RIGHT;}

Daraus erzeugt der Compiler eine Klasse, die ungefähr so aussieht:public class Direction extends Enum<Direction> { public static final Direction NONE = new Direction("NONE", 0); public static final Direction UP = new Direction("UP", 1); public static final Direction DOWN = new Direction("DOWN", 2); public static final Direction LEFT = new Direction("LEFT", 3); public static final Direction RIGHT = new Direction("RIGHT", 4);

private Direction(String name, int index) { super(name, index); } // Alle Werte ermitteln public static Direction[] values() { /* ... */ }

// weitere Methoden ...}

<<enumeration>>Direction

NONEUPDOWNLEFTRIGHT

Stereotyp

Page 212: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 212

Aufzähltypen Einführung

Vorteil von Aufzähltypen gegenüber finalen int-Werten: In einem switch-Block kann der Compiler testen, ob alle Werte eines Typs einen case-

Block haben. Der Benutzer kann anhand des Typs dessen Bedeutung erkennen. Der Typ kann nur die erlaubten Werte annehmen.

Was bietet die Basisklasse Enum noch (Auswahl)? public String name(): Name des Aufzählwertes (z.B. "LEFT")

Beispiel: String name = Direction.LEFT.name(); public int ordinal(): Index eines Wertes in der Aufzählung (z.B. 3 für der Wert

Direction.LEFT, weil LEFT als vierter Wert angegeben ist, Zählung zählt beginnt bei 0)Beispiel: int index = Direction.LEFT.ordinal();

public static <T extends Enum<T>> valueOf(Class<T> enumType, String name): Ermittelt aus dem Namen den AufzählwertBeispiel: Direction dir = Enum.valueOf(Direction.class, "UP");

Page 213: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 213

Aufzähltypen Einführung

Ein Aufzähltyp kann in Pacman für zwei Aufgaben eingesetzt werden: Richtung, in die sich eine Figur bewegt

public enum Direction { NONE, UP, DOWN, LEFT, RIGHT;}

Position einer Zelle, an der sich ein Rahmen befindet.- Problem: Eine Zelle kann an mehr als einer Position einen Rahmen haben.- Lösung: Bitkombination als zusätzlichen Wert dem Aufzähltyp übergeben ersetzt

nicht den Index (Aufruf ordinal()).public enum Direction { // noch unvollständig NONE(0), UP(1), DOWN(2), LEFT(4), RIGHT(8), ALL(15);}

Die zweite Variante wird auch für die Richtung verwendet, wobei ALL unsinnig ist. Beispiele:

LEFT | UP | DOWN RIGHT

Page 214: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 214

Aufzähltypen Methoden und Attribute

Wie funktioniert die Übergabe zusätzlicher Parameter an einen Aufzählwert genau? Dieses Beispiel ergibt Übersetzungsfehler, weil der entsprechende Konstruktor fehlt:public enum Direction { NONE(0), UP(1), DOWN(2), LEFT(4), RIGHT(8), ALL(15);}

Aufzähltypen dürfen zusätzliche Konstruktoren, Attribute und Methoden erhalten:public enum Direction { NONE(0), UP(1), DOWN(2), LEFT(4), RIGHT(8), ALL(15);

private int value;

private Direction(int value) { this.value = value }

public int getValue() { return value; }

// weitere Methoden}

Konstruktoraufruf

Page 215: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 215

Aufzähltypen Methoden und Attribute

Aufzähltypen dürfen auch Schnittstellen implementieren. Sie können aber nicht von Klassen erben, weil sie intern bereits Enum<E> als Basisklasse

besitzen.

Page 216: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 216

Regeln und Hinweise Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 217: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 217

Regeln und Hinweise Wichtige Methoden und Operatoren einer Java-Klasse

Welche Methoden und Operatoren haben eine besondere Bedeutung (kleine Auswahl, hier anhand der Klasse Ghost)?

Methode/Operator Bedeutung

Ghost() Standardkonstruktor. Wird immer dann automatisch erzeugt, wenn kein eigener Konstruktor geschrieben wurde.

protected void finalize() Wird aufgerufen, bevor das Objekt gelöscht wird.

public boolean equals(Object s)

Kommt noch…

public String toString() Wird aufgerufen, wenn eine String-Darstellung des Objektes benötigt wird.

Page 218: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 218

Regeln und Hinweise Wichtige Methoden und Operatoren einer Java-Klasse

Identität und Gleichheit zweier Objekte (hier anhand der Klasse Ghost):

Methode/Operator Bedeutung

Ghost gh1 = new Ghost();Ghost gh2 = new Ghost();if (gh1.equals(gh2))

Inhaltlicher Vergleich der Objekte. Dazu sollte die Methode equals der Klasse Ghost überschrieben werden.

Ghost gh1 = new Ghost();Ghost gh2 = new Ghost();if (gh1 == gh2)

Identität der Objekte. Dazu werden die Referenzen auf die Objekte verglichen. Sind diese identisch, so handelt es sich um dasselbe Objekt.

Page 219: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 219

Regeln und Hinweise Wichtige Methoden und Operatoren – Vergleich von Objekten

Bedingungen für die Gleichheit zweier Objekte: Die Gleichheitsprüfung ist reflexiv: A ist gleich A. Die Gleichheitsprüfung ist symmetrisch: A ist gleich B ==> B ist gleich A. Die Gleichheitsprüfung ist transitiv: A ist gleich B und B ist gleich C ==> A ist gleich C.

Jede Implementierung muss diese Bedingungen einhalten! Problem: Wie sieht der Vergleich bei Vererbung aus?

-xPos: int-yPos: int

Figure

+equals(o: Object): boolean

-dangerous: boolean

Ghost

+equals(o: Object): boolean

Die equals-Methode vergleichtdie Positionen der Figuren

Die equals-Methode vergleichtdie Positionen und dieGefährlichkeit der Geister

Page 220: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 220

Regeln und Hinweise Wichtige Methoden und Operatoren – Vergleich von Objekten

Ohne Beweis: Der Vergleich von Objekten unterschiedlicher Klassen führt zur Verletzung mindestens einer Regeln.

Konsequenz: Nur Objekte identischer Klassen werden überhaupt auf Gleichheit überprüft. Beispiel:

public class Figure { private int xPos; private int yPos; // ... @Override public boolean equals(Object o) { if (o != null && o.getClass() == getClass()) { Figure f = (Figure) o; return xPos == f.xPos && yPos == f.yPos; } return false; }}

public class Ghost extends Figure { private boolean dangerous; // ... @Override public boolean equals(Object o) { return super.equals(o) && ((Ghost) o).dangerous == dangerous; }}

Page 221: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 221

Regeln und Hinweise Wichtige Methoden und Operatoren – Vergleich von Objekten

Erklärung des Beispiels: Die Basisklasse Figure testet mit getClass() zunächst auf identische Klassen. Nur dann werden die Attribute vergleichen. Die abgeleitete Klasse Ghost lässt die Basisklasse die Gleichheit feststellen und prüft

dann das zusätzliche Attribut. Anmerkung:

In der Praxis ist es manchmal auch sinnvoll, nur die Basisklasse ohne Test auf Klassengleichheit die Prüfung vornehmen zu lassen hängt von der Aufgabe ab.

Dann können eine Figur und ein Geist gleich sein!

Page 222: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 222

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Und noch etwas gibt es bei Vererbung zu beachten, Beispiel: Die Klasse LoggingVector erbt von der Basisklasse Vector (Vererbung der

Implementierung). LoggingVector protokolliert zusätzlich alle Aktionen von Vector. Die Methode clear wird nicht überschrieben, weil sie intern setValue aufruft.

Vector

+Vector(size: int)+setValue(index: int, value: E)+getValue(index: int): E+clear()

LoggingVector

+LoggingVector(size: int)+setValue(index: int: value: E)+getValue(index: int): E

-values: E[*]

setValue und getValue protokollieren die Aktion und rufen die Methoden der Basisklasse auf.

public void clear() { for (int i = 0; i < values.length; i++) setValue(null, i);}

E: class

E: class

Page 223: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 223

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Wo ist jetzt das Problem? Eine Änderung an der Basisklasse führt dazu, dass die abgeleitete Klasse nicht mehr korrekt

funktioniert.

Beim Aufruf von clear erfolgt kein Logging mehr!

Vector

+Vector(size: int)+setValue(index: int, value: E)+getValue(index: int): E+clear()

LoggingVector

+LoggingVector(size: int)+setValue(index: int, value: E)+getValue(index: int): E

-values: E[*]

setValue und getValue protokollieren die Aktion und rufen die Methoden der Basisklasse auf.

Kein Aufruf von setValue mehrpublic void clear() { for (int i = 0; i < values.length; i++) values[ i ] = null;}

kein Aufruf

E: class

E: class

Page 224: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 224

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Problem der instabilen Basisklassen (Fragile Base Class Problem): Anpassungen an einer Basisklasse führen zu unerwartetem Verhalten von abgeleiteten

Klassen. Konsequenz: Anpassungen an Basisklassen können häufig nicht vorgenommen werden,

ohne den Kontext der abgeleiteten Klassen mit einzubeziehen. Problem: Die Wartung objektorientierter Systeme, die häufig die Vererbung der

Implementierung nutzen, wird stark erschwert. Konsequenz: Vererbung der Implementierung darf nicht eingesetzt wird, wenn spätere

Änderungen an den Basisklassen wahrscheinlich sind. Ziel: Reine Vererbung der Spezifikation. Die Vermeidung von Redundanzen, kann auch

über Delegationsbeziehungen erreicht werden. Anmerkung: Wenn die abgeleitete Klasse sich exakt an die Spezifikation der Basisklasse hält

und die Spezifikation später auch nicht verändert wird, ist das Erben einer Implementierung problemlos möglich.

In der Praxis: Niemand spezifiziert das Verhalten exakt…

Page 225: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 225

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Lösung mit Delegation:

Vector

+Vector(size: int)+setValue(index: int, value: E)+getValue(index: int): E+clear()

LoggingVector

+LoggingVector(size: int)+setValue(index: int, value: E)+getValue(index: int): E+clear()

-values: E[*]-size: int

<<Interface>>VectorInterface

+setValue(index: int, value: T)+getValue(): E+clear()

LoggingVector delegiert die Aufrufe an Vector weiter, nachdem die Log-Ausgaben erfolgt sind.

E: class

E: class E: class

Page 226: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 226

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Unvollständige Implementierung des Beispiels:public class LoggingVector<E> implements VectorInterface<E> { private Vector<E> vector;

public LoggingVector(int size) { vector = new Vector<E>(size); }

@Override public void setValue(int index, E value) { // Log-Ausgaben, z.B. hier vereinfacht auf dem Bildschirm System.out.println("Neuer Wert " + value + " an Position " + index + " im Vektor"); vector.setValue(value, index); } // usw.}

Änderungen an der Implementierung von Vector beeinflussen nicht die Funktionsfähigkeit von LoggingVector.

Neue Methoden im Vector müssen auch in der Schnittstelle deklariert werden können so nicht in LoggingVector vergessen werden.

Page 227: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 227

Regeln und Hinweise Probleme bei Vererbung – Instabile Basisklasse

Fazit: Vererbung der Spezifikation ist sicherer in Bezug auf Änderungen. Vererbung der Implementierung erfordert häufig weniger Code teilweise aber

automatisch generierbar (z.B. in Eclipse). Wenn sich Vererbung der Spezifikation leicht umsetzen lässt, ist diese Form der

Vererbung vorzuziehen.

Page 228: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 228

Klassendiagramme Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 229: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 229

Klassendiagramme Beziehungen zwischen Klassen

Zwischen Klassen können unterschiedliche Beziehungen bestehen. Die Beziehungen lassen sich ja nach Aufgabe in unterschiedliche Kategorien einteilen.Kategorien in der UML: Assoziation Aggregation und Komposition („Teil und Ganzes“) Vererbung (von einer Spezifikation, von einer Implementierung) schon bekannt

Page 230: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Definition: Binäre AssoziationEine binäre Assoziation beschreibt die semantische Beziehung zwischen zwei Klassen.

Beispiel:

Pacman und GameController „kennen“ sich. Beide Klassen können auf der jeweils anderen Operationen aufrufen.

Informatik 2 - Einführung in Java und UML 230

Assoziation

GameController Pacman

Page 231: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Leserichtung (GameController steuert Pacman):

Multiplizität (wie viele Objekte können gleichzeitig an der Beziehung beteiligt sein):

Informatik 2 - Einführung in Java und UML 231

Leserichtung

GameController Pacmansteuert

Name der Assoziation

Der Controller steuert mindestens einen, max. beliebig viele Figuren.

GameController Figuresteuert

max. Anzahl Controller im Spiel

1 1..*

Page 232: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Rolle (sie beschreibt, welche Funktion/Rolle eine an einer Assoziation beteiligten Klasse einnimmt):

Zweck einer Rolle:- Besseres Verständnis der Assoziation- Name des Attributs in der Implementierung

Informatik 2 - Einführung in Java und UML 232

Grosshaendler Haendler

-verkaeufer

Sichtbarkeitder Rolle

Endkunde

-kaeufer

Nameder Rolle

-verkaeufer

-kaeufer

Page 233: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Implementierungsbeispiel, in dem der Name der Rolle den Namen des Attributes ergibt:public class Haendler { private ArrayList<Grosshaendler> verkaeufer; private ArrayList<Endkunde> kaeufer;

// Methoden usw.}

Im Falle einer automatischen Code-Erzeugung ergeben sich so lesbare Attributnamen im Quelltext.

Achtung: Eine Rolle mit privater Sichtbarkeit kann durch Getter- und Setter-Methoden von „außen“ zugänglich gemacht werden.

Informatik 2 - Einführung in Java und UML 233

Page 234: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Eigenschaft (ähnlich wie Eigenschaften von Attributen geben sie Eigenschaften von Assoziationen nähere Hinweise auf die Umsetzung der Assoziation):

Der Controller benötigt die Figuren in einer bestimmten Reihenfolge (ist in der Beispielimplementierung aber nicht der Fall).

Informatik 2 - Einführung in Java und UML 234

GameController Figure

bearbeitet{ordered}

Eigenschaft

Page 235: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Eigenschaftstypen (unvollständig):- {subsets <Assoziations-Ende>}: Die Menge der Objekte an diesem

Assoziationsende ist eine Teilmenge der Objekte am Assoziationsende <Assoziations-Ende>.

- {union}: Die Menge der Objekte an diesem Assoziationsende ist die Vereinigung aller seiner subsets-Assoziationsenden.Beispiel (die Buchbestellung setzt sich aus den bereits gelieferten und den nicht verfügbaren Büchern zusammen):

Informatik 2 - Einführung in Java und UML 235

Bestellung Buchgeliefert{subsets bestellt}

nicht_vorhanden{subsets bestellt}

/bestellt{union}

Die Menge bestellt ist aus allenTeilmengen abgeleitet. Es kommenkeine weiteren Bücher hinzu.

Page 236: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

- {ordered}: Die so markierten Objekte am Ende der Assoziation liegen sortiert vor. Duplikate sind nicht erlaubt.

- {bag}: Dasselbe Objekt darf am Ende der Assoziation mehrfach erscheinen.- {seq} bzw. {sequence}: Das Ende der Assoziation verweist auf eine geordnete

Menge von Objekten. Duplikate sind erlaubt.

Informatik 2 - Einführung in Java und UML 236

Page 237: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Einschränkung (Teilnahme eines Objektes an einer Assoziation angeben). Einschränkungstypen:

- {or}: Das Objekt muss eine der beiden Assoziationen verwenden.- {xor}: Das Objekt darf nur eine der beiden Assoziationen verwenden.- {and}: Das Objekt muss an beiden Assoziationen teilnehmen lässt sich besser

durch Kardinalität 1 ausdrücken. Beispiel für ein Meilenkonto bei einer Fluggesellschaft:

Informatik 2 - Einführung in Java und UML 237

inhaber

Ein Meilenkontogehört entwedereiner Firma odereiner Person.

Person

inhaber

xorEMail

Anschriftor

Meilenkonto

Eine Person musseine EMail-Adresseoder eine Anschriftangeben.

Firma

Page 238: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Implementierung einer xor-Einschränkung:- Programmgesteuert überprüfen- Durch Vererbung und Einführung einer weiteren Klasse:

Informatik 2 - Einführung in Java und UML 238

inhaber

Person

Firma

JuristischePerson

inhaber

Person

inhaber

xor

Meilenkonto Firma

Meilenkonto

1

Page 239: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Navigierbarkeit (erlaubt die Angabe, in welche Richtung eine Assoziation gelesen wird). Es werden folgende Arten unterstützt:

Navigierbar: Die Klasse Field kennt die Klasse Pacman am Ende der Assoziation.

Nicht navigierbar: Die Klasse Pacman kennt die Klasse Ghost am Ende der Assoziation nicht.

Unspezifiziert: Es wird keine Aussage über die Navigierbarkeit getroffen. In der Praxis wird das häufig als navigierbar interpretiert.

Bidirektionale Navigierbarkeit: Beide Klassen kennen sich gegenseitig und können so auch jeweils die Methoden des Anderen aufrufen.

Informatik 2 - Einführung in Java und UML 239

PacmanField

GhostPacman

PacmanGameController

PacmanGameController

Page 240: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Verbot der Navigierbarkeit: Beide Klasse dürfen sich nicht kennen. Es besteht zwar eine logische Beziehung, die aber nicht durch eine Assoziation ausgedrückt werden soll nicht sehr gebräuchlich.

Unidirektionale Navigierbarkeit: Die Navigation ist in nur einer Richtung erlaubt.

Teilweise Spezifikation der Navigation: Es ist offen gelassen, ob Pacman auch das Field kennt.

Informatik 2 - Einführung in Java und UML 240

PacmanGhost

PacmanField

PacmanField

Page 241: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Implementierung einer Assoziation:

Informatik 2 - Einführung in Java und UML 241

GameController Figure

controls-figures-controller

1..*1

public abstract class Figure { private GameController controller; // ...}

public class GameController { private ArrayList<Figure> figures; // ...}

Page 242: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Reflexive Assoziation: Eine Assoziation einer Klasse zu sich selbst, ansonsten handelt es sich um eine normale Assoziation.

Der Vorgesetzte hat mindestens einen Untergebenen. Jeder Untergebene hat maximal einen Vorgesetzten. Jeder Vorgesetzte kann also auch

wieder Mitarbeiter sein. Implementierungsmöglichkeit:

public class Mitarbeiter { private Mitarbeiter vorgesetzter; private ArrayList<Mitarbeiter> untergebene;

// ...}

Informatik 2 - Einführung in Java und UML 242

-untergebene

-vorgesetzter0..1

*

leitetMitarbeiter

Page 243: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

N-äre AssoziationEine n-äre Assoziation ist die allgemeine Form einer Assoziation zwischen n Klassen.

Erklärung des Beispiels: Die drei Klassen stehen in einer Beziehung namens Menue. Nicht jedes Hauptgericht muss in einem Menü vorkommen (Multiplizität 0). Jedes Hauptgericht kann in beliebig vielen Menüs vorkommen (Multiplizität *). Wenn ein Hauptgericht in mindestens einem Menü vorhanden sein muss, würde man am

Hauptgericht die Multiplizität 1..* eintragen.

Informatik 2 - Einführung in Java und UML 243

DessertHauptgericht

Vorspeise

0..* 0..*

0..*

Menue

Assoziationsname

Page 244: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Wie kann eine n-äre Assoziation implementiert werden? Ganz einfach durch Umsetzung in mehrere binäre Assoziationen:

Informatik 2 - Einführung in Java und UML 244

DessertHauptgericht

Vorspeise

0..* 0..*

0..*

Menue

DessertHauptgericht

Vorspeise

0..* 0..*

0..*Menue

1

1

1

Page 245: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Assoziationsklasse: Eine Assoziationsklasse ist eine Assoziation, die neben Attributen auch Operationen wie bei einer Klasse aufnehmen kann:

Die Namen der Assoziation und ihrer Klasse müssen identisch sein. Einsatz: Zusätzliche Attribute können logisch keinem der Enden der Assoziation

zugeordnet werden Ablage in der Assoziationsklasse. Beispiel: Die Auftragsnummer kann weder der Firma noch dem Kunden zugeordnet werden.

Informatik 2 - Einführung in Java und UML 245

1..* 1..*

Firma KundeAuftrag

Auftrag

-nummer: int Assoziationsklasse

Page 246: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Implementierung: Weder C++ noch Java kennen Assoziationsklassen Einführung einer „Zwischenklasse“:

Der Kunde erteilt beliebig viele Aufträge. Eine Firma kann beliebig viele Aufträge ausführen.

Informatik 2 - Einführung in Java und UML 246

1..* 1..*

Firma KundeAuftrag

Auftrag

-nummer: int

1

Firma KundeAuftrag

-nummer: int1..* 11..*

fuehrtAus erteilt

Page 247: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Assoziation

Implementierung einer Assoziationsklasse:

Informatik 2 - Einführung in Java und UML 247

public class Auftrag { private int nummer; private Kunde kunde; private Firma firma;

// ...}

public class Firma { private ArrayList<Auftrag> auftraege;

// ...}

public class Kunde { private ArrayList<Auftrag> auftraege;

// ...}

Page 248: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Aggregation

Definition: AggregationEine Aggregation ist eine spezielle Form einer binären Assoziation. Sie beschreibt eine Teil-Ganzes-Beziehung zwischen genau zwei Klassen.

Beispiel:

Informatik 2 - Einführung in Java und UML 248

0..*

Field

Figure

0..1

Ganzes

Teil

AggregationDas Teil kennt dasGanze nicht (Pfeilspitze).

Page 249: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Aggregation

Eigenschaften einer Aggregation: Die Lebensdauer des Ganzen ist von der Lebensdauer der Teile unabhängig. Die Lebensdauer der Teile ist von der Lebensdauer des Ganzen unabhängig. Teile können in mehreren Ganzen gleichzeitig verwendet werden. Die Teile kennen das Ganze häufig nicht.

Einsatzgebiete für Aggregation: Das Ganze handelt als Stellvertreter für seine Teile. Es nimmt Aufträge entgegen und delegiert diese an die Teile. Beispiel: Pacman

- Ganzes: Spielfeld- Teile: Einzelne Figuren in der Zeichenfläche- Auftrag: Anforderung, sich neu zu zeichnen- Delegation: Jedes Teil erhält den Auftrag, sich selbst neu zu zeichnen.

Informatik 2 - Einführung in Java und UML 249

Page 250: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Aggregation

Implementierung einer Aggregation:

Hinweise: Das Ganze erzeugt und löscht die Teile i.d.R. nicht selbst. Das Ganze besitzt häufig Methoden zum Hinzufügen und Entfernen von Teilen sowie zum

Besuchen aller Teile.

Informatik 2 - Einführung in Java und UML 250

public class Field { private ArrayList<Figure> figures;

// ...}

public abstract class Figure {

// ...}

Page 251: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Komposition

Definition: KompositionEine Komposition ist eine starke Form der Aggregation. Hier sind das Ganze und seine Teile untrennbar miteinander verbunden.

Beispiel:

Informatik 2 - Einführung in Java und UML 251

0..*

GameController

Figure

Ganzes

Teil

Komposition, Multiplizität ist 1

Das Teil kennt dasGanze nicht (Pfeilspitze).

Page 252: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Komposition

Eigenschaften einer Komposition: Die Lebensdauer des Ganzen ist von der Lebensdauer der Teile unabhängig. Beim

Löschen eines Teils bleibt das Ganze bestehen. Die Lebensdauer der Teile ist von der Lebensdauer des Ganzen abhängig: Beim Löschen

des Ganzen werden die Teile auch gelöscht. Teile können nicht in mehreren Ganzen gleichzeitig verwendet werden. Die Teile kennen das Ganze häufig nicht.

Einsatzgebiete für Komposition siehe Aggregation

Informatik 2 - Einführung in Java und UML 252

Page 253: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Komposition

Spezialfall der Komposition: Multiplizität 0..1

Figuren dürfen außerhalb und ohne Bezug zum Controller erzeugt werden. Sie werden dann als Teile am Controller registriert und gehören ab diesem Zeitpunkt zum

Controller. Figuren dürften auch an einen anderen Controller übertragen werden.

Informatik 2 - Einführung in Java und UML 253

0..1

0..*

GameController

Figure

Page 254: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Komposition

Implementierung einer Komposition (in Java wie bei einer Aggregation):

Hinweise: Häufig ist es sinnvoll, dass das Ganze die Teile selbst erzeugt und löscht: Die Teile können

nicht so versehentlich auch ohne das Ganze verwendet werden. Das Ganze besitzt i.d.R. Methoden zum Erzeugen und Entfernen von Teilen sowie zum

Besuchen aller Teile.

Informatik 2 - Einführung in Java und UML 254

public class GameController { private ArrayList<Figure> figures;

// ...}

public abstract class Figure {

// ...}

Page 255: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Hinweise zur Auswahl

Wann wird ein bestimmter Beziehungstyp verwendet? Existenzabhängige Teil-Ganzes-Beziehung: Komposition Logische Einheit, die nicht existenzabhängig ist: Aggregation Kaskadierende Methodenaufrufe: Aggregation (z.B. Pacman-Spiel, in dem die Spielfläche

die Aufrufe zum Neuzeichnen an die Figuren weiter leitet) Rumbaugh: „Think of Aggregation as a modeling placebo“.

Informatik 2 - Einführung in Java und UML 255

Page 256: Informatik 2 Einführung in Java und UML

Holger Vogelsang

Klassendiagramme Beziehungen zwischen Klassen: Vererbung einer Assoziation

Die Vererbung von Assoziationen wird meist in folgenden Szenarien verwendet: Es besteht bereits eine Assoziation zwischen zwei Basisklassen. Es soll ausgedrückt werden, dass die Assoziation einer abgeleiteten Klasse immer nur mit

der Assoziation einer anderen abgeleiteten Klasse hergestellt werden soll. Beispiel:

Informatik 2 - Einführung in Java und UML 256

Artikel Personschreibt

-autor

1

-artikel

*

Fachartikel Redakteur

Nur der Redakteurkann Fachartikelschreiben EineAssoziation kannz.B. nicht von einer„normalen“ Personzum Fachartikel führen.

Page 257: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 257

Klassendiagramme Übersicht zu Klassendiagramm (vereinfacht)

Darstellung der wichtigsten Elemente durch MagicDraw:

Page 258: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 258

Klassendiagramme Klassen im Pacman-Spiel (unvollständig)

Page 259: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 259

Klassendiagramme Beispiel aus der Klausur WS 2012/2013

Fiktives Flugbuchungssystem: Kunde: Name, Anschrift, E-Mail-Adresse, Angabe (privat/geschäftlich), Login-Name,

Passwort Flug: Flugnummer, Datum, Uhrzeit, Start- und Endflughafen, Gebühr, abhängig vom

Startflughafen, Preis, abhängig von der Klasse (1. Klasse, Business-Klasse, 2. Klasse). Es werden alle Sitze einer Klasse zum selben Preis angeboten.

Buchung: Jeder Kunde kann beliebig viele Flugbuchungen gleichzeitig vornehmen. Eine Buchung kann mehrere Sitzplätze in derselben Klasse umfassen. Die Zahlungsart müssen Sie nicht berücksichtigen.

Reservierung: Ist sich ein Kunde noch nicht ganz sicher, ob er einen Flug buchen möchte, dann kann er sich diesen für einen Zeitraum von 24 Stunden kostenlos reservieren.

Zusatzoptionen bei der Buchung: Zu einem Flug können optionale Leistungen hinzugebucht werden, für die aber zusätzliche Kosten anfallen (Reiserücktrittsversicherung, Sitzplatz am Notausstieg, Übergepäck, eventuell weitere (je nach Fluggesellschaft und Flugzeugtyp)).

Page 260: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 260

Fehlerbehandlung mit Ausnahmen Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 261: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 261

Fehlerbehandlung mit Ausnahmen Motivation

Welche Arten von Fehlern gibt es? Wie können Laufzeitfehler sicher gefunden werden? Wie sollten Laufzeitfehler einer Methode dem Aufrufer mitgeteilt werden?

Page 262: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 262

Fehlerbehandlung mit Ausnahmen Fehlerklassifikation

Erwartete Fehler durch Aufruf einer prinzipiell unsicheren Methode Auftreten: Es muss bei jedem Aufruf mit dem Fehler gerechnet werden. Beispiel: Versuch, eine Datei zum Lesen zu öffnen, die nicht existiert Vermeidung: nicht möglich Behandlung: ja

Unerwartete Fehler durch Programmierfehler oder mangelnde Systemressourcen Auftreten: Eigentlich sollte der Fehler nie auftreten. Beispiel: zu wenig Hauptspeicher vorhanden, Stacküberlauf Vermeidung: nur begrenzt möglich (intensive Programmtests) Behandlung: nur begrenzt möglich (z.B. Datensicherung vor der Programmbeendigung)

Page 263: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 263

Fehlerbehandlung mit Ausnahmen Fehlerklassifikation

Sonderfall: Erwarteter oder unerwarteter Fehler während der Fehlerbehandlung Auftreten: siehe erwarteter und unerwarteter Fehler Beispiel: Die Fehlermeldung kann wegen fehlender Schreibrechte oder zu geringen freien

Hauptspeichers nicht in eine Datei geschrieben werden. Vermeidung: nur bei sehr einfacher Fehlerbehandlung möglich Behandlung: hängt vom Fehler ab

Page 264: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 264

Fehlerbehandlung mit Ausnahmen Reaktionen auf Fehler

Sofort behandelbarer Fehler Auswirkung: Das Programm kann auf den Fehler reagieren und seine Arbeit (eventuell

eingeschränkt) fortsetzen. Reaktion: ignorieren (wenn sinnvoll möglich), alternativen Programmablauf starten Beispiel: Bei fehlender Eingabedatei werden immer Standardwerte angenommen.

Nicht sofort behandelbarer Fehler Auswirkung: Der Fehler kann an der Stelle, an der er auftritt, nicht behandelt werden. Reaktion: Fehlermeldung an den Aufrufer der Methode Beispiel: Datei existiert nicht sollen Standardwerte verwendet werden/soll der

Benutzer gefragt werden? Kann eventuell an der Stelle des Fehlers nicht entschieden werden.

Nicht sinnvoll behandelbarer Fehler Auswirkung: sinnvolle Programmfortsetzung nicht möglich Reaktion: i.d.R. Programmbeendigung mit vorheriger Datensicherung (sofern möglich) Beispiel: Stacküberlauf, schwere Programmierfehler

Page 265: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 265

Fehlerbehandlung mit Ausnahmen Exceptions – Idee

Fehlerbehandlung bisher: Ein Methode m1 stellt einen Fehler fest und liefert ein Ergebnis, das diesen Fehler

beschreibt. Die aufrufende Methode m2 der Methode m1 stellt fest, dass m1 einen Fehler

zurückliefert und beendet die eigene Arbeit mit der Rückgabe eines Fehlers. usw...

Schlechte Lösung, da sich eventuell große Teile einer Methode mit der Fehlerbehandlung befassen. Eine Trennung von Fehler- und Normalfall ist nicht vorhanden.

Fehler werden häufig über viele Aufrufebenen hinweg nach „oben“ weitergereicht, ohne dass die Fehler direkt bearbeitet werden.

Java bietet das Konzept der Ausnahme (Exception) zur besseren Fehlerbehandlung. Damit muss nicht der Rückgabewert einer Methode zur Fehlerübermittlung missbraucht werden.

Page 266: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 266

Fehlerbehandlung mit Ausnahmen Exceptions – Idee

Einsatzgebiete Meldung von Fehlern, die nicht lokal am Ort der Entstehung behoben werden konnten:

Beispielsweise kann der Autor einer Bibliothek Laufzeitfehler („Datei existiert nicht“ etc.) zwar erkennen, er ist aber selten in der Lage, diese im Kontext des aufrufenden Programms richtig zu behandeln.

Der Anwender der Bibliothek dagegen weiß, wie er mit den Fehlern umgehen soll. Die Behandlung von anderswo gefundenen Fehlern. Syntax:

try { // versuche, eine Aufgabe zu lösen}catch (Fehlerklasse fehler) {

// behandle Fehler des Typs "Fehlerklasse"}

Page 267: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 267

Fehlerbehandlung mit Ausnahmen Exceptions – Idee

Beispiel (Zugriff auf den Vektor, angelehnt an ArrayList):public class Vector<E> { private E[] values; private int size; // ... public E getValue(int index) { if (index >= size || index < 0) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); return values[ index ]; }}

public static void main(String[] args) { Vector<Double> vector = new Vector<>(3, 0.0);

try { System.out.println(vector.getValue(0)); System.out.println(vector.getValue(4)); } catch (IndexOutOfBoundsException ex) { System.err.println("Oops" + ex.getMessage()); }}

Page 268: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 268

Fehlerbehandlung mit Ausnahmen Mehrere Exceptions

Behandlung mehrerer Ausnahmen Syntax:

try { // versuche, eine Aufgabe zu lösen}catch (FehlerTyp1 ex1) { // behandle Fehler-Typ1}catch (FehlerTyp2 ex2) { // behandle Fehler-Typ2}

Unbehandelte Ausnahmen: Beendigung der Methode Auslösung der Ausnahme in der aufrufenden Methode Dieses Spiel funktioniert solange, bis eine Methode die Ausnahme abfängt oder das

Programm beendet wurde.

Page 269: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 269

Fehlerbehandlung mit Ausnahmen Mehrere Exceptions

Es dürfen auch mehrere, unabhängige Fehler durch ein sogenanntes „multi-catch“ abgefangen werden:

Syntax:try { // versuche, eine Aufgabe zu lösen}catch (FehlerTyp1 | FehlerTyp2 ex) { // behandle Fehler-Typ1 und Fehler-Typ 2}

Page 270: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 270

Fehlerbehandlung mit Ausnahmen Mehrere Exceptions

Ausnahmen werden in den catch-Blöcken in der Reihenfolge ihres Auftretens ausgewertet. Abfangen aller möglichen Ausnahmen:

try { // versuche, eine Aufgabe zu lösen}catch (FehlerTyp1 ex) {

// behandle Fehler-Typ1}catch (Throwable thr) { // Alle unbehandelten Fehler // behandle alle anderen Fehler}

Ausnahmen können auch im catch-Block ausgelöst werden:try { // versuche, eine Aufgabe zu lösen}catch (FehlerTyp1 ex) {

// behandle Fehler-Typ1 throw ex; // Fehler weitermelden}

Page 271: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 271

Fehlerbehandlung mit Ausnahmen Exceptions mit Klassenhierarchien

Exception-Klassen können ganze Klassenhierarchien bilden. Im catch-Block kann auch die Basisklasse einer Ausnahme angegeben werden, um eine

Ausnahme einer abgeleiteten Klasse abzufangen. Beispiel:

public class FileNotFoundException extends IOException { // ...}

Eine FileNotFoundException kann jetzt auch durch die Angabe ihrer Basisklasse abgefangen werden:public void m() { try { // … throw new FileNotFoundException(); } catch (IOException ex) { // … }}

Page 272: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 272

Fehlerbehandlung mit Ausnahmen Exceptions mit Klassenhierarchien

Es können auch mehrere catch-Blöcke vorhanden sein, die sowohl die abgeleitete Klasse als auch die Basisklasse der Ausnahme abfangen. Achtung Reihenfolge:public void m() { try { // ... throw new FileNotFoundException(); } catch (IOException ex1) { // ... } catch (Throwable thr) { // ... }}

Wird erst Throwable abgefangen, dann wird der catch-Block von IOException nie betreten.

Page 273: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 273

Fehlerbehandlung mit Ausnahmen Exceptions: Hinweise

Generelle Ausräumarbeiten nach einem erfolgreichem try oder einer Ausnahme mit finally. Beispiel:public void m() { try { // ... throw new FileNotFoundException(); } catch (IOException ex1) { // ... } finally { // Wird immer betreten }}

Ein „echtes“ Beispiel folgt im nächsten Kapitel. Seit Java 7 gibt es ein erweitertes try-Konstrukt siehe Kapitel zur

Ein-/Ausgabebehandlung.

Page 274: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 274

Fehlerbehandlung mit Ausnahmen Exceptions mit Klassenhierarchien

Arten der Ausnahmen:

gelb: unerwartete und in der Regel nicht sinnvoll behandelbare Fehler grün: unerwartete und in der Regel nicht sinnvoll behandelbare Fehler („Programmierfehler“) rot: erwartete und sofort oder später behandelbare Fehler (erben direkt von Exception,

nicht von RuntimeException)

Page 275: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 275

Fehlerbehandlung mit Ausnahmen Eigenschaften und Deklaration erwarteter Fehler

Erwartete und sofort oder später behandelbare Fehler (rot markiert): Einem Anwender einer Methode muss die Art der Ausnahme, die diese auslösen kann,

angegeben werden. Syntax:

ret-type method-name(params) throws ExceptionsBeispiel:public int readFromFile(String name) throws FileNotFoundException, EOFException {Beispiel durch Angabe der Basisklasse IOException (FileNotFoundException und EOFException erben davon):public int readFromFile(String name) throws IOException {

Ohne Spezifikation kann die Methode nur unerwartete oder gar keine Ausnahmen auslösen.Beispiel:public int getValue(int index) {

Page 276: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 276

Funktionale Programmierung Übersicht

Überladen

Gener. Klassen

Aufzähl-typen

Regeln

Java undUML

Schritte,Software KlassendiagrammeObjekt-

orientierung

Klassen,Objekte

Fehler

Zusicher-ungen

Ausnahmen

Über-schreiben

Vererbung

FunktionaleProgrammierung

Page 277: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 277

Funktionale Programmierung Einführung

Funktionale Programmierung Das Programm besteht u.A. aus einer Anzahl Funktionen, die sich gegenseitig aufrufen

können. Syntax in LISP für einen Funktionsaufruf:

(Funktionsname Param1 ... ParamN)(+ 2 4) ; ruft Funktion + auf, die die Summe von 2 und 4 zurückgibt

Rein funktionale Programmiersprachen:- Funktionen besitzen keine Nebeneffekte (keine Manipulation von Zuständen), geben

nur Ergebnisse zurück Funktionen im mathematischen Sinn. Funktionen höherer Ordnung: Funktionen können als Parameter übergeben werden.

Page 278: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 278

Funktionale Programmierung Einführung

Das Lambda-Kalkül war einer der ersten Ansätze, solche funktionalen Programme zu beschreiben:

Funktionsabstraktion: λ x.A (anonyme Funktion mit x als Eingabeparameter und Funktionsdefinition A), x hat keinen Typ

Funktionsanwendung: F A (Funktion F wird auf den Ausdruck A angewendet) Beispiele:

Identität: λ x.x x2: λ x.x*x, angewandt auf 3: (λ x.x*x)3 ergibt 9

Was soll das in einer Java-Einführung???? Seit Java 8 bietet Java einen recht eleganten Ansatz zur funktionalen Programmierung.

Page 279: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 279

Funktionale Programmierung Einführung

Rückblick auf den „Vergleicher“ mit der generischen Schnittstelle Comparator<T>:public class Customer { // ... private int number; // Getter und Setter}

Vergleicher für zwei Kundenobjekte:public class CustomerNumberComparator implements Comparator<Customer> { @Override public int compare(Customer c1, Customer c2) { return c1.getNumber() – c2.getNumber(); }}

Hinweis damals: Es wird eine „Funktion“ in einem Objekt gekapselt.

Page 280: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 280

Funktionale Programmierung Einführung

Warum kann die Funktion nicht direkt übergeben werden? Die Funktion erwartet zwei Objekte der Klasse Customer. Die Funktion gibt ein Ergebnis vom Typ int zurück. Java unterstützt seit Version 8 die Übergabe solcher unbenannter Funktionen, auch

Lambdas genannt. Die Funktionen werden zu Methoden in Klassen, die Schnittstellen implementieren.

Beispiel Comparator:Customer[] customers;// customer füllen

StattArrays.sort(customers, new CustomerNumberComparator());

EinfacherArrays.sort(customers, (c1, c2) -> c1.getNumber() - c2.getNumber());

Die Klasse CustomerNumberComparator wird überflüssig!

Page 281: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 281

Funktionale Programmierung Einführung

Was passiert hier?

Vorhandene Methodesort(T[] arg0, Comparator<? super T> arg1)

Vorhandene Schnittstellepublic interface Comparator<T> { int compare(T arg0, T arg1); // ...}

Aufrufsort(customers, (c1, c2) -> c1.getNumber() - c2.getNumber())

benötigt

benötigteParameter

Methodenrumpf

Erzeugter Aufruf mit anonymer innerer Klassesort(customers, new Comparator<Customer>() { @Override public int compare(Customer c1, Customer c2) { return c1.getNumber() - c2.getNumber(); } });

benötigterRückgabetyp

übergebeneParameter

Page 282: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 282

Funktionale Programmierung Einführung

Warum benötigen im Aufruf die Parameter c1 und c2 keine Typangabe?sort(customers, (c1, c2) -> c1.getNumber() - c2.getNumber())

Der Compiler kann die Typen selbst ermitteln: customers ist vom Typ Customer[]. Damit wird der generische Parameter T in der aufgerufenen Methode eine Customer-

Klasse: sort(T[] arg0, Comparator<? super T> arg1) Der generische Typ im Comparator muss also auch Customer oder eine Basisklasse

davon sein. Die compare-Methode der Schnittstelle Comparator besitzt zwei Übergabeparameter

vom Typ T, also auch vom Typ Customer. Damit sind die beiden Parameter c1 und c2 vom Typ Customer.

Page 283: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 283

Funktionale Programmierung Lambda-Ausdrücke

Lambda-Ausdrücke werden dadurch umgesetzt, dass anonyme innere Klassen Schnittstellen implementieren.

Die Schnittstellen dürfen nur eine abstrakte Methode besitzen. Weitere default- oder statische Methoden sind erlaubt.

Solche Schnittstellen werden auch funktionale Schnittstellen (functional interfaces) genannt: Sie erlauben die Übergabe einer „Funktion“. Sie können mit der Annotation @FunctionalInterface markiert werden. Im Paket java.util.function gibt es bereits sehr viele solcher Schnittstellen.

Die übergebenen Objekte anonymer innerer Klassen werden als Funktions-Objekte (functional objects) oder Funktoren (functors) bezeichnet Code als Objekt!

Page 284: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 284

Funktionale Programmierung Lambda-Ausdrücke

Welche Schnittstelle wird nun zum Sortieren verwendet? Sie muss zwei Parameter desselben Typs akzeptieren und einen int-Wert als

Ergebniszurückgeben generische Schnittstelle. Beispiel: Namen anhand ihrer Länge sortieren (Wiederholung Comparator):

String[] names = {"Z", "D", "Y", "B"};Arrays.sort(names, (n1, n2) -> n1.length() - n2.length());

Oder etwas länger:Comparator<String> comp = (o1, o2) -> o1.length() - o2.length();Arrays.sort(names, comp);

Page 285: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 285

Funktionale Programmierung Lambda-Ausdrücke

Weiteres Beispiel: Durchlaufen einer Datenstruktur (kommt später noch genauer). „Klassisch“:

ArrayList<String> names = new ArrayList<>();// füllenfor (int i = 0; i < names.size(); i++) { System.out.println(names.get(i));}

Immer derselbe Aufbau: Schleife, mit dem eigentlichen Inhalt Warum nicht den eigentlichen Inhalt als Funktion übergeben?

names.forEach(n -> System.out.println(n)); forEach erwartet ein Objekt, dessen Klasse die Schnittstelle Consumer<T>

implementiert, vereinfacht:@FunctionalInterfacepublic interface Consumer<T> { void accept(T);}

Comsumer: erwartet einen Wert, gibt nichts zurück („konsumiert“)

Page 286: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 286

Funktionale Programmierung Lambda-Ausdrücke

Es geht noch einfacher mit einer Methodenreferenz:names.forEach(System.out::println);

:: leitet einen Verweis auf eine Methode (hier println) ein. Der Compiler untersucht, ob die Methode einen Wert des Typs String (names ist eine

ArrayList<String>) erwartet und erzeugt automatisch ein Objekt der inneren Klasse.

Hinweise zur Syntax: (int x, int y) -> x + y:

- Typangaben sind nur erforderlich, wenn der Compiler sie nicht selbst ermitteln kann.- Bei mehr als einem Parameter sind Klammern links erforderlich.

(x, y) -> x + y: Der Compiler kann die Typen von x und y selbst bestimmen. x -> 2 * x: Bei einem Parameter sind die Klammern nicht erforderlich. () -> 42: Ohne Parameter müssen leere Klammern („burger“) gesetzt werden. System.out::println: Methodenreferenz als Kurzform für

x -> System.out.println(x) Customer::new: Referenz auf einen Konstruktor

Page 287: Informatik 2 Einführung in Java und UML

Holger Vogelsang Informatik 2 - Einführung in Java und UML 287

Funktionale Programmierung Lambda-Ausdrücke

In vielen Datenstrukturen müssen die Lamda-Ausdrücke frei von Nebeneffekten sein: Sie dürfen die Datenstruktur, auf der sie aufgerufen werden, nicht verändern. Sie dürfen keine anderen Daten verändern.

Viele weitere Beispiele zu Lambda-Ausdrücken kommen in den Kapiteln zu JavaFX und Datenstrukturen.