Grundkonzepte der objektorientierten Programmierung Teil 3 Klaus Becker
Grundkonzepte der objektorientierten Programmierung Teil 3 Klaus Becker 2006
Objektorientierte Modellierung 2 1 4 2 5 3 1$ 6 1$ 1$ 1$ Miniwelt Modell System
3 Teil 1 Vererbung
Zielsetzung 4 Beim Würfelspiel „chuck a luck“ soll einer der Würfel durch ein Glücksrad ersetzt werden. Ziel ist es, die sich hierdurch ergebenden Änderungen im Modell zu untersuchen. 1 4 2 5 1$ 6 3 24 5 1 36 1$ 1$ 1$
Modellierung 5 Eine strukturgetreue, an der Miniwelt orientierte Modellierung zeigt neben zwei Würfel-Objekten auch ein Glücksrad-Objekt. Miniwelt Modell TWuerfel augen position werfen drehen instance of 24 5 1 36 TGluecksrad instance of wuerfel. A wuerfel. B rad augen = 3 position = 5
6 Implementierung mit Code-Duplizierung unit u. Wuerfel; interface TWuerfel – augen: integer unit u. Gluecksrad; interface TGluecksrad – position: integer type + create TWuerfel =. . + werfen implementation + get. Augen: integer type + create TGluecksrad =. . + drehen implementation + get. Position: integer constructor TWuerfel. create; begin augen : = random(6)+1; end; constructor TGluecksrad. create; begin position : = random(6)+1; end; procedure TWuerfel. werfen; begin augen : = random(6)+1; end; procedure TGluecksrad. drehen; begin position : = random(6)+1; end; function TWuerfel. get. Augen: . . begin result : = augen; end; function TGluecksrad. get. Posit. . begin result : = position; end; end.
Universelle Klasse zur Vermeidung. . . 7 Zur Vermeidung unnötiger Code-Duplizierung kann man eine universelle Klasse „TZufallsgeraet“ einführen, mit deren Hilfe Objekte erzeugt werden können, die mit Hilfe der Methode „aktivieren“ eine Zufallszahl aus dem Bereich 1. . 6 erzeugen können. // Erzeugung der Objekte TZufallsgeraet wuerfel. A : = TZufallsgeraet. create; wuerfel. B : = TZufallsgeraet. create; rad : = TZufallsgeraet. create; – wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) // Aktivierung der Objekte wuerfel. A. aktivieren; wuerfel. B. aktivieren; rad. aktivieren; instance of wuerfel. A wuerfel. B rad wert = 3 wert = 5
. . . von Code-Duplizierung 8 Vorteil: Man benötigt nur eine Klasse zur Erzeugung der gewünschten Objekte. Nachteil: Unterschiede zwischen Würfel-Objekten und Glücksrad-Objekten können nicht erfasst werden. TZufallsgeraet – wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) instance of wuerfel. A wuerfel. B rad wert = 3 wert = 5
9 Kleine Unterschiede Zur Verdeutlichung „kleiner Unterschiede“ soll das Chuck-A-Luck-Spiel jetzt mit einem universellen Zufallsgerät, einem Würfel und einem Glücksrad durchgeführt werden. Dabei gehen wir von folgenden Annahmen aus: Ein TZufallsgeraet-Objekt soll nach der Erzeugung einen unbestimmten (vom Compiler beliebig festgelegten) Wert haben. Ein TWuerfel-Objekt soll ein spezielles TZufallsgeraet-Objekt sein, das nach der Erzeugung eine nicht vorhersagbare Augenzahl aus dem Bereich 1. . 6 hat. Ein TGluecksrad-Objekt soll ein spezielles TZufallsgeraet-Objekt sein, das nach der Erzeugung immer auf Position 1 eingestellt ist. Zudem soll ein solches Objekt über eine Methode „stoppen“ verfügen, mit deren Hilfe die Anfangsposition eingestellt werden kann. 3 24 5 1 36
Kleine Unterschiede 10 Die Klasse TWuerfel bzw. die Klasse TGluecksrad ist hier eine Erweiterung der Klasse TZufallsgeraet – wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) ist TWuerfel TGluecksrad + create instance of 3 24 5 1 36 + create + stoppen instance of geraet wuerfel rad wert = 3 wert = 5
11 Vererbung Eine Erweiterung einer „Superklasse“ erbt alle Attribute und Methoden dieser Klasse. Eine solche „Subklasse“ kann weitere Attribute und Methoden besitzen. Sie kann auch ererbte Methoden überschreiben (d. h. neu festlegen). TZufallsgeraet Superklasse – wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) ist TWuerfel Subklasse TGluecksrad + create Vererbung ermöglicht es, eine Klasse als Erweiterung einer anderen Klasse zu konzipieren. instance of + create + stoppen instance of geraet wuerfel rad wert = 3 wert = 5
12 Implementierung der Superklasse unit u. Zufallsgeraet; TZufallsgeraet interface – wert: integer type TZufallsgeraet =. . + create + aktivieren + get. Wert: integer + set. Wert(w: integer) implementation constructor TZufallsgeraet. cre. . begin Keine Initialisierung end; procedure TZufallsgeraet. aktiv. . begin augen : = random(6)+1; end; function TZufallsgeraet. get. Wer. . begin result : = wert; end; ist TWuerfel TGluecksrad + create instance of + create + stoppen instance of . . . geraet wuerfel rad end. wert = 3 wert = 5
13 Implementierung einer Subklasse unit u. Wuerfel; TZufallsgeraet interface – wert: integer uses u. Zufallsgeraet; + create + aktivieren + get. Wert: integer + set. Wert(w: integer) type TWuerfel = class(TZufallsgeraet) public constructor create; end; ist TWuerfel implementation constructor TWuerfel. create; begin inherited create; aktivieren; end. ist TGluecksrad + create instance of + create + stoppen instance of geraet wuerfel rad wert = 3 wert = 5
14 Implementierung einer Subklasse unit u. Gluecksrad; TZufallsgeraet interface – wert: integer uses u. Zufallsgeraet; + create + aktivieren + get. Wert: integer + set. Wert(w: integer) type TGluecksrad = class(TZufallsgeraet) public constructor create; procedure stoppen; end; ist TWuerfel TGluecksrad implementation constructor TGluecksrad. create; begin inherited create; set. Wert(1); end; procedure TGluecksrad. stoppen; begin set. Wert(1); end; . . . + create instance of + create + stoppen instance of geraet wuerfel rad wert = 3 wert = 5
15 Vererbung und Zugriffsrechte type TZufallsgeraet = class private wert: integer; public. . . type TGluecksrad = class(TZufallsgeraet) public constructor create; procedure stoppen; end; implementation constructor TGluecksrad. create; begin inherited create; wert : = 1; Fehler end; TZufallsgeraet – wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) ist TWuerfel + create ist TGluecksrad + create + stoppen Die privaten Attribute der Superklasse sind in den Subklassen nicht zugreifbar.
16 Vererbung und Zugriffsrechte type TZufallsgeraet = class protected wert: integer; public. . . type TGluecksrad = class(TZufallsgeraet) public constructor create; procedure stoppen; end; implementation constructor TGluecksrad. create; begin inherited create; wert : = 1; Ok! end; TZufallsgeraet # wert: integer + create + aktivieren + get. Wert: integer + set. Wert(w: integer) ist TWuerfel + create ist TGluecksrad + create + stoppen Die Attribute der Superklasse sind hier auch in den Subklassen zugreifbar.
17 Erzeugung von Subklassen-Objekten unit u. Gluecksrad; interface uses u. Zufallsgeraet; type TGluecksrad = class(TZufallsgeraet) public constructor create; procedure stoppen; end; implementation constructor TGluecksrad. create; begin inherited create; set. Wert(1); end; procedure TGluecksrad. stoppen; begin set. Wert(1); end; . . . Im Konstruktor einer Subklasse muss zunächst der Konstruktor der Superklasse aufgerufen werden.
18 Erzeugung von Subklassen-Objekten unit u. Gluecksrad; interface Fehlt dieser Aufruf, so wird er automatisch vom Compiler ergänzt. uses u. Zufallsgeraet; type TGluecksrad = class(TZufallsgeraet) public constructor create; procedure stoppen; end; implementation constructor TGluecksrad. create; begin inherited create; set. Wert(1); end; procedure TGluecksrad. stoppen; begin set. Wert(1); end; . . .
19 Aufgabe Erstellen Sie ein Chuck-A-Luck-System wie beschrieben. Die Klasse TZufallsgeraet kann weiter verallgemeinert werden. Z. B. könnte der Bereich der möglichen Zufallszahlen erweitert werden. Führen Sie die erforderlichen Veränderungen durch.
20 Aufgabe unit u. Wuerfel; interface type TWuerfel = class(TObject) private augen: integer; public constructor create; procedure werfen; function get. Augen: integer; end; implementation constructor TWuerfel. create; begin inherited create; augen : = random(6)+1; end; . . . Testen Sie die gezeigte Implementierung der Klasse TWuerfel (z. B. in einer Version Chuck. ALuck 2. . ) und erklären Sie die markierten Zusätze. Informieren Sie sich hierzu auch über die in Delphi vordefinierte Klasse TObject.
21 Teil 2 Polymorphie
Zielsetzung 22 Das Würfelspiel „chuck a luck“ soll – ohne dass der Benutzer es weiß – mal mit idealen, mal mit gezinkten Würfeln gespielt werden. 1 4 2 5 3 1$ 6 1$ 1$ 1$
Modellierung 23 Bei einem gezinkten Würfel sollen die Augenzahlen 1. . 6 mit ungleicher Wahrscheinlichkeit auftreten (z. B. 1: 50%, 2: 10%, 3: 10%, . . . ). TIdealer. Wuerfel TGezinkter. Wuerfel augen werfen instance of wuerfel. A wuerfel. B wuerfel. C augen = 3 augen = 5 augen = 1
24 Modellierung Ideale und gezinkte Würfel werden als Spezialisierung eines „allgemeinen“ Würfels konzipiert, der beim Werfen nichts machen soll. TWuerfel - augen: integer + create + werfen // nichts machen + get. Augen: integer + set. Augen(a: integer) ist TIdealer. Wuerfel TGezinkter. Wuerfel werfen // Augen von 1. . 6
25 Implementierungsversuch unit u. Wuerfel; interface type TWuerfel = class private augen: integer; public constructor create; procedure werfen; function get. Augen: integer; procedure set. Augen(a: int. . end; implementation constructor TWuerfel. create; begin augen : = 1; end; procedure TWuerfel. werfen; begin end; . . . TWuerfel - augen: integer + create + werfen // nichts machen + get. Augen: integer + set. Augen(a: integer) ist TIdealer. Wuerfel werfen // Augen von 1. . 6 ist TGezinkter. Wuerfel werfen // Augen von 1. . 6
Implementierungsversuch 26 unit u. Gezinkter. Wuerfel; interface uses u. Wuerfel; type TGezinkter. Wuerfel = class(TWuerfel) public procedure werfen; end; implementation procedure TGezinkter. Wuerfel. werfen; var hilf: real; begin hilf : = random; if hilf < 0. 5 then set. Augen(1) else if hilf < 0. 6 then set. Augen(2) else if hilf < 0. 7 then. . . TWuerfel - augen: integer + create + werfen // nichts machen + get. Augen: integer + set. Augen(a: integer) ist TIdealer. Wuerfel werfen // Augen von 1. . 6 ist TGezinkter. Wuerfel werfen // Augen von 1. . 5 Die Klasse „TIdealer. Wuerfel“ wird analog implementiert.
27 Implementierungsversuch . . . type TSpielmanager = class private zustand: integer; wuerfel. A: TWuerfel; wuerfel. B: TWuerfel; wuerfel. C: TWuerfel; konto: TKonto; spielbrett: TSpielbre. . public constructor create; procedure wuerfel. Werfen. . . procedure. . . wuerfel. Werfen; begin wuerfel. A. werfen; wuerfel. B. werfen; wuerfel. C. werfen; end; type TGUI = class(TForm). . . private { Private-Deklarationen } wuerfel. A, wuerfel. B, . . . : TWuerfel; . . . procedure TGUI. Form. Create(Sender: TOb. . var hilf: integer; begin {Wahl der Würfel} randomize; hilf : = random(2); if hilf = 0 then {erzeuge ideale Würf. } begin wuerfel. A : = TIdealer. Wuerfel. create; wuerfel. B : = TIdealer. Wuerfel. create; wuerfel. C : = TIdealer. Wuerfel. create; end else {erzeuge gezinkte Würfel} begin wuerfel. A : = TGezinkter. Wuerfel. create; wuerfel. B : = TGezinkter. Wuerfel. create; wuerfel. C : = TGezinkter. Wuerfel. create; . . .
28 Statischer / dynamischer Typ type TGUI = class(TForm). . . private { Private-Deklarationen } wuerfel. A, wuerfel. B, . . . : TWuerfel; . . . procedure TGUI. Form. Create(Sender: TOb. . var hilf: integer; begin {Wahl der Würfel} randomize; hilf : = random(2); if hilf = 0 then {erzeuge ideale Würf. } begin wuerfel. A : = TIdealer. Wuerfel. create; wuerfel. B : = TIdealer. Wuerfel. create; wuerfel. C : = TIdealer. Wuerfel. create; end else {erzeuge gezinkte Würfel} begin wuerfel. A : = TGezinkter. Wuerfel. create; wuerfel. B : = TGezinkter. Wuerfel. create; wuerfel. C : = TGezinkter. Wuerfel. create; . . . procedure. . . wuerfel. Werfen; begin wuerfel. A. werfen; wuerfel. B. werfen; wuerfel. C. werfen; end; Deklaration: statischer Typ Laufzeit: dynamischer Typ Dynam. Typ: TIdealer. Wuerfel Statischer Typ: TWuerfel
29 Frühe Bindung / späte Bindung procedure. . . wuerfel. Werfen; begin wuerfel. A. werfen; . . . end; Bei früher Bindung ist der statische Typ für die Ausführung einer Methode ausschlaggebend. Bei später Bindung wird die Suche der Methode beim dynamischen Typ begonnen. Dynam. Typ: TIdealer. Wuerfel Statischer Typ: TWuerfel
30 Implementierung von später Bindung type TWuerfel = class private augen: integer; public constructor create; procedure werfen; virtual; . . . end; procedure. . . wuerfel. Werfen; begin wuerfel. A. werfen; . . . end; implementation procedure TWuerfel. werfen; begin end; . . . type TIdealer. Wuerfel = class(TWuerfel) public procedure werfen; override; end; implementation procedure TIdealer. Wuerfel. werfen; begin set. Augen(random(6)+1); end; . . . Dynam. Typ: TIdealer. Wuerfel Statischer Typ: TWuerfel
31 Implementierung von früher Bindung type TWuerfel = class private augen: integer; public constructor create; procedure werfen; . . . end; procedure. . . wuerfel. Werfen; begin wuerfel. A. werfen; . . . end; implementation procedure TWuerfel. werfen; begin end; . . . type TIdealer. Wuerfel = class(TWuerfel) public procedure werfen; end; implementation procedure TIdealer. Wuerfel. werfen; begin set. Augen(random(6)+1); end; . . . Dynam. Typ: TIdealer. Wuerfel Statischer Typ: TWuerfel
32 Abstrakte Methoden type TWuerfel = class private augen: integer; public constructor create; procedure werfen; virtual; abstract; . . . end; implementation // keine Implementierung von werfen type TIdealer. Wuerfel = class(TWuerfel) public procedure werfen; override; end; implementation procedure TIdealer. Wuerfel. werfen; begin set. Augen(random(6)+1); end; . . . Abstrakte Methoden werden in der Superklasse nur deklariert und erst in Subklassen implementiert.
Polymorphie 33 Methodenaufrufe können polymorph gestaltet werden. Derselbe Methodenaufruf kann zur Laufzeit zu verschiedenen Zeitpunkten verschiedene Methoden aufrufen, abhängig vom jeweiligen dynamischen Typ der für den Aufruf verantwortlichen Variablen. zunächst später
34 Aufgabe Erstellen Sie ein Chuck-A-Luck-System wie beschrieben. Fügen Sie einen Button hinzu, um das Chuck-A-Luck-Spiel neu zu initialisieren. Dabei soll auch neu festgelegt werden, mit welchen Würfeln (ideal, gezinkt) gespielt wird.
35 Aufgabe unit u. Wuerfel; interface type TWuerfel = class(TObject) private augen: integer; public constructor create; destructor destroy; override; procedure werfen; function get. Augen: integer; end; . . . Erklären Sie die markierte Stelle. Informieren Sie sich hierzu auch über die in Delphi vordefinierte Klasse TObject.
36 Teil 3 Zusammenfassung
Objektorientierung 37 Klasse Beziehung Grundkonzepte Vererbung Polymorphie Nachricht Objekt Grundideen Modellierungssprache: UML Implementierungssprache: Delphi, Java, . . .
38 Idee: Objekt als Baustein Objekte / Klassen sollten nach Möglichkeit so abstrakt entworfen werden, dass sie zur Erledigung vieler Aufgaben benutzt werden können (Wiederverwendung). Gut verwendbare Klassen können dann in Klassenbibliotheken zur weiteren Verwendung bereitgestellt werden.
39 Literaturhinweise Es gibt eine Vielzahl von fachwissenschaftlichen Darstellungen zur objektorientierten Modellierung und Programmierung. Hier wurden folgende Lehrwerke benutzt: - D. J. Barnes, M. Kölling: Objektorientierte Programmierung mit Java. Pearson Studium 2003. - Helmut Balzert: Lehrbuch Grundlagen der Informatik. Spektrum Ak. Verlag 1999. - Bernd Oestereich: Objektorientierte Softwareentwicklung. Oldenbourg 1998. Dagegen gibt es nur wenige Schulbücher, die systematisch in die objektorientierte Programmierung einführen, z. B. : - Siegfried Spolwig: Objektorientierung im Informatikunterricht. Dümmler-Verlag 1997. - P. Damann, J. Wemßen: Objektorientierte Programmierung mit Delphi, Band 2. Klett-Verlag 2003. Viele interessante Artikel mit Unterrichtsvorschlägen bzw. fachdidaktischen Auseinandersetzungen findet man in der Zeitschrift LOG IN. Das Themenheft 128/129 ist speziell dem Thema „Objektorientiertes Modellieren und Programmieren“ gewidmet. .
40 Literaturhinweise Im Internet findet man ebenfalls sehr viele schulgerechte Darstellungen der objektorientierten Modellierung und Programmierung, z. B: http: //informatikag. bildung-rp. de/ Die AG-Informatik des LMZ in RLP stellt u. a. auch Fortbildungsmaterialien zu diesem Thema bereit. http: //hsg. region-kaiserslautern. de/faecher/inf/index. php Auf der Homepage des HSG in Kaiserslautern findet man Unterrichtsmaterialien und Links zu weiteren interessanten Seiten. .
- Slides: 40