© Prof. Dr. Andreas Solymosi

Objektorienter Unterricht von Programmiersprachen

In diesem Konzept für Programmiersprachunterricht wird angenommen, dass

·         das objektorientierte Paradigma ein wichtigeres Konzept beim Programmieren ist als die klassischen Sprachelemente (primitive Typen und Steuerstrukturen)

·         das Paradigma eines Programmierers in hohem Maße von den ersten Konzepten geprägt wird, die er erlernt.

·         ein didaktisch aufbereitetes Paket geeigneter fürs Lernen ist als die Standardpakete

Aus diesem Grund werden hier zuerst die objektorientierten Konzepte ohne die klassischen vermittelt. Das mathematisch-didaktische Prinzip der Schritt-für-Schritt-Führung wird angewendet: (Möglichst) keine Sprachelemente werden verwendet, die erst später erläutert werden. Dafür werden die schon erläuterten Elemente (zur Vertiefung und Einübung) möglichst immer wieder verwendet. Nicht erklärte Bibliothekselemente werden jedoch von Anfang an verwendet – eine wichtige Fähigkeit zur Abstraktion

Java als Unterrichtsprache ist für diese Vorgehensweise geeignet.

1. Woche

Thema 1.1: Einführung ins Programmieren

Daten, Algorithmen, Kapselung.

Quellprogramm (.java), übersetztes Programm (.class), statisches (nicht in Java) und dynamisches Binden. Dokumentation (mit javadoc) und Archive (.jar)

Übersetzen (mit javac) und Ausführen (mit java oder appletviewer)

Thema 1.2: Klassen und Methoden

Leere Klasse (Definition, Kopf, leerer Rumpf; reservierte Wörter, Namen; Zeilenkommentar); Fehlermeldung des Compilers (beim Schreibfehler wie „Class“) und des Interpreters (mit der leeren Klasse)

Das übliche Hallo-Welt-Programm enthält viele, erst später zu erläuternde Sprachelemente. Deswegen ist es besser, mit der leeren Klasse anzufangen – dies ist das einfachste Programm, das übersetzt werden kann – mit nur wenigen Sprachelementen.

Ausblick: Benutzung von vorhandenen Klassen: Erweiterung, static-Aufruf, Instanziierung

Leere Erweiterung der leeren Klasse (Mehrzeilenkommentar; UML-Darstellung der Erweiterung); Compiler-Fehlermeldung „cannot find symbol“

„Erweiterung“ in Java ist ein besserer Ausdruck als die übliche „Vererbung“ – selbst wenn hier auch die Erweiterung leer ist.

(Leere) Erweiterung der leeren Klasse aus einem Paket; Paket als Namensraum; Bibliothek installieren (.jar, CLASSPATH)

Die didaktisch aufbereitete Bibliothek enthält eine leere Klasse, die hier erweitert wird.

Thema 1.3: Erben von Methoden

Nichtleere Klasse erweitern à ausführbar (mit Appletviewer), leeres Applet

Appletviewer erzeugt ein Objekt der auszuführenden Klasse, deswegen ist er einfacher zu benutzen als der java-Interpreter. Die zu erweiternde Klasse aus der Bibliothek ist ein leeres Applet

Klasse HalloWelt erweitern à Animation im Applet

Im Gegensatz zum üblichen Hallo-Welt-Programm wurden hier alle verwendete Sprachelemente schon erklärt; die Funktionsweise der erweiterten Klasse bleibt jedoch verborgen. Dies ist wichtig für Abstraktionsfähigkeit – auch in den Standardbibliotheken gibt es viele verborgene Funktionalitäten.

Mehrfache Erweiterung

Die erweiterte HalloWelt-Klasse wird nochmals erweitert – an einem UML-Diagramm sollen die Beziehungen erläutert werden.

Leeres Überschreiben einer Methode à Keine Animation sichtbar

Profil einer Methode: Zugriffschutz (public), Ergebnistyp (void), Name, Parameterliste (leer)

Definition einer Methode: Kopf, Rumpf (leer)

Aufruf einer geerbten Methode

Hinzufügen einer Methode; private Methode; Aufruf der eigenen Methode

Parameter (vom Typ String) à Animation einer Zeichenkette

Profil der aufzurufenden Methode; protected

Mehrere Parameter

Überladen einer Methode

Aufruf einer statischen Methode aus einer anderen Klasse

Import

Dokumentation einer Klasse; Dokumentationskommentare

Übung

Editor, Übersetzen, Ausführen vom DOS-Prompt

Erweiterung von Klassen; Definition und Aufruf von Methoden

2. Woche

Thema 2.1: Klasse mit Gedächtnis

Eine Klasse mit (statischem) Gedächtnis hat verschiedene Zustände

Klasse mit statischem Konstruktor, die sich im Appletfenster anzeigt

Methodenaufrufe  – Aufruf einer statischen Methode, die den Zustand verändert und dies anzeigt.

Aufrufsequenzen (Änderung des Zustandes)

Statisches und dynamisches Ende – Unterbrechung einer Sequenz (return)

Reihenfolgebedingungen, Ausnahmen (beim Fehler in der Sequenz)

Die Zustandsveränderungen dürfen nur in einer bestimmten Reihenfolge durchgeführt werden, ansonsten werden Ausnahmen ausgelöst

Ausnahmebehandlung: try/catch

Ausnahmeverteiler: mehrere catch-Blöcke

Ausnahmedokumentation: throws

Geprüfte und ungeprüfte Ausnahmen à Fehler zu Übersetzungs- bzw. Laufzeit

„Unreported Exception“

Auffangen (try/catch) oder Weiterreichen (throws)

3. Woche

Thema 3.1: Objekt

Instanziierung einer Klasse (new)

Referenz und Objekt – Objektdiagramm (mit Variablen und Objekten)

Methodenaufruf für ein Objekt

Zustandsveränderung, ähnlich wie 2.1 für eine Klasse

Mehrere Referenzen, mehrere Objekte in einer Sequenz

Die Standardklasse String

NullPointerException

 „Umbiegen“ einer Referenz, Zuweisung

Verloren gegangenes Objekt, Zwei Referenzen auf ein Objekt

Typprüfung

Lokale und globale Referenzen

Zugriffschutz: public, protected, private, „paketweit“

static-Regel: Klasse.methode() nur wenn static – sonst new

Thema 3.2: Pakete

Paket- und Verzeichnisstruktur; Übersetzen und Ausführen aus dem Wurzelverzeichnis

Geschachtelte Pakete: Benutzung, Vereinbarung

Keine echte Schachtelung von Paketen, nur des Namensraumes

Dokumentation eines Pakets (mit javadoc)

Anhand der (einfachen) Bibliothek für den Unterricht soll die Benutzung der Dokumentation antrainiert werden.

Dokumentationsklauseln

Dokumentationskommentar einer Klasse, einer Methode

Dokumentation der Standardpakete

Thema 3.3: Applet

Standardpaket Applet à leeres Applet

Überschreiben: start, init, paint à Konzept ”Framework“

Der Interpreter (das Framework) ruft verschiedene Methoden zu verschiedenen Ereignissen auf

Beispielapplet: paint mit drawString

Hauptprogramm main (ohne Erklärung von String[])

Erklärung von java.lang.System.out.println: Paket, Unterpaket, Klasse, static-Referenz, Methode, Parameter

Jetzt bleibt im klassischen Hallo-Welt-Programm nur noch String[] unerklärt, sonst ist alles verständlich – auch die verborgene Funktionalität von println

Implizite Erweiterung: java.lang.Object

Impliziter Import: java.lang.*

Thema 3.4: Schachtelungen

Statische Schachtelung (des Programmtextes mit {}) für den Compiler, Sichtbarkeit

Dynamische Schachtelung (des Ablaufs durch Aufrufe) für den Interpreter, Lebensdauer

Name (Methode, Referenz) – sichtbar im Block

lokale Variable (Referenz) – lebt im Block

Der Stapel (stack)

Sichtbarkeitsstufen in Java: lokal, privat, paketweit, geschützt, öffentlich, statisch

Innere Klassen

Blöcke

Geschachteltes try-catch

Rekursive Aufrufe, Abbruch einer Rekursion

4. Woche

Thema 4.1: Parameterübergabe

formaler Parameter (Definition, lokale Variable), aktueller Parameter (Aufruf, Ausdruck)

Veränderung von Parametern – Frage: Nach dem Aufruf veränderter oder ursprünglicher Wert?

Call by value / Call by reference

Veränderung des Parameterobjekts: Call by reference – veränderter Wert

Veränderung der Parameterreferenz: Call by value – ursprünglicher Wert

Variablen: lokal (auf dem Stapel), global (in Objekten auf der Halde/heap), static (in Klassen)

Thema 4.2: Programmierung von Klassen mit Zustand

Mit Hilfe von vorhandenen Klassen aus der Bibliothek werden ähnliche aber komplexere Klassen implementiert

Objektvariable (globale Referenz)

public Variable (von außen veränderbar – inkonsistenter Objektszustand)

static = ohne Objekt (der umgebenden Klasse) benutzbar

Regel: in static-Methode nur static

Aufruf einer Objektmethode aus static main

Klassenvariable (static-Referenz)

Objekt- und Klassenvariablen gemischt

Thema 4.3: Ausnahmen

Verbreitung von Ausnahmen (über den Stapel weitergereicht)

von Methode zu Methode über die Aufrufhierarchie

Ausnahme-Strategien: unverändert weiterreichen, auffangen und behandeln, auffangen und eine andere Ausnahme auslösen, auffangen und dieselbe Ausnahme auslösen

Ausnahmeobjekt, Ausnahmeklasse vereinbaren

Standard-Ausnahmeklassen: Throwable, Error, Exception, RuntimeException, NullPointerException

Ausnahmeobjekt versorgen

Vor throw kann das Ausnahmeobjekt beschrieben, im catch-Block gelesen werden.

Thema 4.4: Klassenkonstruktor

static-Block

Jetzt wird die Funktionalität der Klasse aus 2.1 verständlich, wie sie sich hat anzeigen können

Thema 4.5: Diagramme

Klassendiagramm (UML), Objektdiagramm

Thema 4.6: Syntax

Syntaktische Begriffe, nichtterminale Symbole, terminale Symbole, Metasymbole

The Java Language Specification

5. Woche

Thema 5.1: Konstruktor

Klassen- und Objektkonstruktor; Überladen des Konstruktors; Aufruf des Konstruktors

Kopierkonstruktor; Destruktor

Konzepte aus C++:  finalize() in Java

const- und final-Referenzen

Unterschied zwischen const und final (Objekt bzw. Referenz unveränderbar) – Umsetzung in Java: a) nur im Kommentar b) immutable Klassen

Thema 5.2: Wiederverwendung

Strategien: Programmtext kopieren, Klasse instanziieren („einkaufen“), Klasse erweitern („erben“)

Interface = „unfertige Klasse“

Implementierung eines Interface

Referenz vom Interfacetyp

Mehrfachbeerbung (Erweiterung) von Interfaces

Gleichzeitiges Implementieren und Erweitern

Abstrakte Klasse = „halbfertige Klasse“

Thema 5.3: Aufwärtskompatibilität

Kompatibilität bei Zuweisung (oder Parameterübergabe) von unterschiedlichen Typen

Aufwärts = von unten nach oben in der Klassenhierarchie – problemlos, implizit

Abwärts = von oben nach unten in der Klassenhierarchie – nur explizit

Explizite Typkonvertierung (Casting)

Erfolgreiche Abwärtskompatibilität

Erfolglose Abwärtskompatibilität à ClassCastException – hängt vom Objekt ab

Polymorphie – Frage: welche Methode? Antwort: hängt vom Objekt (nicht von der Referen) ab

6. Woche

Thema 6.1: Werte und Funktionen

Explizites Setzen des Objektzustandes

Die Klasse aus 3.1 exportiert Aufzählungswerte, die als Parameter der Zustandsveränderungsmethode gegeben werden können.

Lesen des Objektzustandes mit Hilfe einer Funktion

Funktion = nicht-void-Methode

Aufruf einer Funktion (syntaktisch): rechte Seite einer Zuweisung, aktueller Parameter eines Aufrufs, Ziel eines Methodenaufrufs

Wirkungsloser Funktionsaufruf – Funktionsergebnis wird vergessen (in Java leider möglich, von C/C++ übernommen)

Vergleich Prozeduren (void-Methoden) und Funktionen

Implementierung von Funktionen: return

Thema 6.2: Standardfunktionen

Applet-Funktionen

Beispiel Applet.play

Geschachtelte Funktionsaufrufe

Beispiel Graphics.drawImage

Beispiel Graphics.getImage

Unterschied Applet.init/paint

Um das Applet zu optimieren, sollte getImage in init, drawImage in paint aufgerufen werden

7. Woche

Thema 7.1: Programmierung von Oberflächen

JApplet, JButton – mit Objektdiagramm

JComboBox

Grafische Oberflächen

Anordnung (layout) der Fensterkomponenten: FlowLayout, GridLayout, JPanel

Grafik: paint, drawLine, usw.

8. Woche

Thema 8.1: Ereignissteuerung

Mögliche Strategien: Ergänzen vom Programmtext, Überschreiben leerer Methoden,

Überschreiben abstrakter Methoden, Listener

Registrieren eines Listeners

Interface als Parametertyp: addActionListener

Anonyme Referenz (new als Parameter), Anonyme Klasse

Anonyme Referenzen können benutzt werden, wenn das Objekt nur einmal benutzt (als Parameter übergeben) wird. Anonyme Klassen können benutzt werden, wenn sie nur einmal benutzt (instanziiert) wird.

Anonyme Implementierung (von ActionListener)

Listener: WindowListener, KeyListener, MouseListener, usw.

Mehrzweckklasse

Eine Klasse, die sowohl ein Applet wie auch ein Listener ist – unsauber aber üblich

Verteilung der Ereignisse: Zwei Buttons, zwei Listener

Menüs: Aufbau, Menüsteuerung

Die swing-Behälterhierarchie

9. Woche

Thema 9.1: Primitive Typen

Aufzählungstypen

Arten von Aufzählungstypen: ordnungsfrei, geordnet, zyklisch

Aufzählungsmethoden – Beispiel: next, previous

boolean

arithmetische Typen: Fließkommatypen (float, double), Ganzzahltypen (int, char, long, short, byte)

Ein Wert, mehrere Namen: 5.0 und 5.00, 'a' und '\u0097'

char, Sonderliterale (escape sequences)

Ganzzahlliterale: dezimal, oktal, hexadezimal - Syntax

Bruchtypen, Bruchliterale

Diskrete Folge von Bruchzahlen: 7007.0 - 7007.0078125 - 7007.015625

Folge großer Bruchzahlen: 10000000000.0 - 10000001024.0 - 10000002048.0

Sonderwerte: Float/Double.NEGATIVE_INFINITY, usw.

Explizite Konvertierung von primitiven Werten

Genauigkeitsverlust: int i = 1234567890; float f = i; 1234567936.0

Erweiternde und einschränkende Konvertierungen

Thema 9.2: Operatoren

Interpretation von Operatoren als Methoden (in C++)

Gleichheit, Ungleichheit – Referenz- und Objektgleichheit, Object.equals

Ordnungsoperatoren (nur für arithmetische Typen)

Logische Operatoren (nur für boolean): diadisch (&, |, ^), monadisch (!)

Kurzgeschlossene (short cut) Operatoren: && und ||

Boolesche Zuweisungen

Arithmetische Operatoren - Division für Bruch- oder Ganzzahl

Restberechnung (Modulo)

Arithmetische Zuweisungsoperatoren

Ergebnistyp der Operatoren

Ganzzahl-Überlauf, Bruchüberlauf

Hüllenklassen, Methoden, Werte

java.math.BigDecimal/Integer

Bindungsstärke

Kombination von Operatoren: Operatoren gleicher Bindungsstärke

Bedingungsoperator

Assoziativität von Operatoren

10. Woche

Thema 10.1: Steuerstrukturen: Verzweigung

Sequenz

Ein/Zweiweg-Alternative, Syntax

Mehrweg-Alternative (Fallunterscheidung) –

switch ohne break - Zusammengefaßte Zweige

switch mit enum

Thema 10.2: Steuerstrukturen: Zählergesteuerte Wiederholung

foreach-Schleife

Syntax: foreach, for

Ausführung der for-Schleife

for-Schleife ≠ Zählschleife

Zählschleife = spezielle for-Schleife, Kriterien

Leere Schleife, Endlosschleife

Abarbeitung von Zeichenketten

Fakultät

Geschachtelte Zählschleife

Thema 10.3: Steuerstrukturen: Bedingungsgesteuerte Wiederholung

Vor- und nachprüfende (kopf- und fußgesteuerte) Schleife (while, do-while)

Mitteprüfende (rumpfgesteuerte) Schleife (while(true) if-break)

Fortsetzungsbedingung, Unterbrechungsbedingung

Verwendung der Schleifenarten: Durchwandern einer Datei/Liste, Endekriterium einlesen

Gleichwertigkeit der bedingungsgesteuerten Wiederholungsarten

Thema 10.4: Rekursion

Fakultät rekursiv/iterativ

Fibonacci-Zahlen rekursiv/iterativ

Die Türme von Hanoi

11. Woche

Thema 11.1: Reihungen

Zeichenketten, mutable Zeichenketten (StringBuffer, StringBuilder)

char-Reihung

Vereinbarung und Zugriff (schreiben, lesen)

IndexOutOfBoundsException

Bearbeitung von Zeichenketten/Reihungen: Zählen, Sortieren (bubbleSort)

Reihungsreferenz, Reihungsobjekt

Sortieren von Objekten

Comparable

Kommandozeilenparameter

Variable Parameterzahl – Beispiel: java.io.PrintStream.format, Formatierungsregeln

Reihungsliteral

Elementtyp als Reihung à Mehrdimensionale Reihung, Geschachteltes Rehungsliteral

12. Woche

Thema 12.1: Implementierung einer einfachen Collection

interface Warteschlange (queue), interface Stapel (stack)

Gruppierung von Collections nach Zugriff (wahlfrei, gebunden), Elementtyp (fest, beliebig, generisch), Größe (fest, Konstruktor, dehnbar, dynamisch)

Beispiel für Verwendung Warteschange: Arztpraxis

Implementierung des Ganzzahlstapels als Reihung

Leerer/voller Stapel

eintragen/lesen/entfernen

Objektstapel

Stapel mit Vector

Generischer Stapel

Vorteil: kein ClassCastException beim lesen

Einschränkung des Typparameters: Comparable

Sortieren mit Comparable

Sortieren mit Comparator

Zusicherungen: invariant, assert, requires, ensures

invariant, requires und ensures gibt es in Eiffel; in Java können sie mit assert nachgebaut werden

Übung 12: Implementierung der Warteschlange

Ringpuffer mit %

Testtreiber: Dialog, batch

Literatur

Programmieren mit Java (4. Auflage) - Vieweg Verlag, 2008


Leitseite

© Prof. Dr. Andreas Solymosi