Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Vererbung Helmut Paulus Speyer, 7./8.11.2006. OOP: Vererbung 2 Teil 1 Grafik mit Delphi.

Ähnliche Präsentationen


Präsentation zum Thema: "Vererbung Helmut Paulus Speyer, 7./8.11.2006. OOP: Vererbung 2 Teil 1 Grafik mit Delphi."—  Präsentation transkript:

1 Vererbung Helmut Paulus Speyer, 7./

2 OOP: Vererbung 2 Teil 1 Grafik mit Delphi

3 OOP: Vererbung 3 Zeichenfläche TCanvas Canvas-Objekte dienen als Zeichenfläche für grafische Elemente. Sie kapseln eine Vielzahl von Methoden zur Ausgabe von Grafik und Text in einem rechteckigen Bereich. TCanvas moveto(x,y : integer); lineto(x, y : integer); ellipse(x1,y1,x2,y2 : integer) rectangle(x1,y1,x2,y2 : integer) polygon(p : array of Tpoint); TextOut(x, y: Integer; const Text: string);... Brush : TBrush Pen : TPen Font : TFont... Pinsel – Füllfarbe, Muster... Stift – Linienfarbe, Stil... Schriftart – Farbe, Schrifttyp... Der Koordinatenursprung (0,0) ist in der linken oberen Ecke einer Komponenten, die ein Canvas-Objekt zur Verfügung stellen. TCanvas-Werkzeuge Pen, Brush und Font, zuständig für bestimmte Teilaufgaben:

4 OOP: Vererbung 4 Wie erhält man ein TCanvas-Objekt? TCanvas-Objekte werden von einigen Delphi-Komponenten als Property zur Verfügung gestellt: z. B.: Formular, Paintbox, Image, Bitmap Der Koordinatenursprung ist die linke obere Ecke der jeweiligen Komponente. Die positive y-Achse zeigt nach unten. Die Image-Komponente speichert die Graphik zusätzlich in einer Hintergrundbitmap, so dass das Bild automatisch anzeigt wird, wenn das Formularfenster, nachdem es verdeckt war, wieder in den Vordergrund geholt wird. Das Formular und Paintbox zeichnen das Bild nur einmalig. Damit es nach dem Verdecken wieder erscheint, muss das Zeichnen der Graphik in der OnPaint-Ereignismethode der jeweiligen Komponente erfolgen. Dieses Ereignis wird vom Betriebssystem automatisch ausgelöst. Der Koordinatenursprung ist die linke obere Ecke der jeweiligen Komponente. Die positive y-Achse zeigt nach unten. Die Image-Komponente speichert die Graphik zusätzlich in einer Hintergrundbitmap, so dass das Bild automatisch anzeigt wird, wenn das Formularfenster, nachdem es verdeckt war, wieder in den Vordergrund geholt wird. Das Formular und Paintbox zeichnen das Bild nur einmalig. Damit es nach dem Verdecken wieder erscheint, muss das Zeichnen der Graphik in der OnPaint-Ereignismethode der jeweiligen Komponente erfolgen. Dieses Ereignis wird vom Betriebssystem automatisch ausgelöst.

5 OOP: Vererbung 5 Objekthierarchie Das Bild-Objekt Bild vom Typ TImage verwaltet über das Attribut Canvas ein Leinwand-Objekt der Klasse TCanvas, das wiederum ein Zeichenstift-Objekt der Klasse TPen und ein Malpinsel-Objekt der Klasse TBrush verwaltet. Die entsprechenden Attribute Pen und Brush werden als Property zur Verfügung gestellt. Beispiel: Blaues Rechteck Bild.Canvas.Brush.Color := clbue; Bild.canvas.rectangle(10,10,100,20); Beispiel: Blaues Rechteck Bild.Canvas.Brush.Color := clbue; Bild.canvas.rectangle(10,10,100,20); Pinselfarbe blau Rechteck mit der linken oberen Ecke am Punkt (X1, Y1) und der rechten unteren Ecke am Punkt (X2, Y2).

6 OOP: Vererbung 6 Aufgaben 1 1.Testen Sie das Beispielprogramm Grafiktest 2.Variieren Sie verschiedene Modi der Pinsel und Stifte Testen Sie insbesondere den NotXOR-Füllmodus 3.Das Programm soll wie folgt verbessert werden: Nach Wahl Kreise, Rechtecke oder Polygone zeichnen Position und Größe der Figur interaktiv durch Mausklicks bestimmen -Kreis: Kreismittelpunkt und Radius -Rechteck/Polygon: Eckpunkte

7 OOP: Vererbung 7 Zustandsbasierte Ablaufmodellierung Alter Zustand Auslösende Aktion Ausgelöste Aktion Neuer Zustand Z0AuswahlBoxClickPunktefeld inizialisierenZ1 FormMausDown Punkt speichern [letzter Punkt] Figur zeichnen Z1 Z0 Ablauf: Figur auswählen Punkte bestimmen Figur zeichnen Z0 Bereit Für Auswahl der Figur Z1Figur gewählt für Punktaufnahme aktiviert Zustände: Eine Figur soll erzeugt werden:

8 OOP: Vererbung 8 Zustandsbasierte Ablaufmodellierung Zustandsautomat : [nicht letzter Punkt] AuswahlBoxClick Punktearray inizialieren Z1: Figur gewählt Z0: Bereit [letzter Punkt] FormMouseDown Figur zeichnen FormMouseDown Punkt aufnehmen Steuerung durch Ereignismethoden: AuswahlBoxClick : Figurtyp wählen FormMouseDown : Punkte speichern bis alle Punkte aufgenommen Steuerung durch Ereignismethoden: AuswahlBoxClick : Figurtyp wählen FormMouseDown : Punkte speichern bis alle Punkte aufgenommen

9 OOP: Vererbung 9 Zustandsbasierte Modellierung Ein Zustandsdiagramm ist immer genau einer Klasse zugeordnet. Es beschreibt das dynamische Verhalten der Objekte. In einem Zustandsdiagramm wird festgehalten: auf welche interne und externe Ereignisse ein Objekt reagiert, wie ein Objekt reagiert und welche Aktivitäten ausgelöst werden, wenn es sich in einem bestimmten Zustand befindet, in welchen Folgezustand ein Objekt übergeht als Reaktion auf ein Ereignis. In einem Zustandsdiagramm wird festgehalten: auf welche interne und externe Ereignisse ein Objekt reagiert, wie ein Objekt reagiert und welche Aktivitäten ausgelöst werden, wenn es sich in einem bestimmten Zustand befindet, in welchen Folgezustand ein Objekt übergeht als Reaktion auf ein Ereignis. Zustandsbasierte Modellierung ist bei der Entwicklung von Systemen immer dann sinnvoll, wenn das Verhalten eines Systems nicht nur von äußeren Eingaben oder Ereignissen abhängt, sondern auch von inneren Zuständen, die das System in Abhängigkeit von den Eingaben bzw. Ereignissen durchläuft. Je nach Zustand kann ein Objekt anders auf dasselbe Ereignis reagieren.

10 OOP: Vererbung 10 Implementierung type TZustand = (z0,z1); TGUI = class(TForm) procedure AuswahlBoxClick(Sender: TObject); procedure FormMouseDown(... X, Y: Integer); private { Private-Deklarationen} Zustand : TZustand; NMax : integer; Punkte : array of TPoint; procedure zeichneFigur; public { Public-Deklarationen} end; Anzahl der Eckpunkte Dynamischer Array als Liste der Eckpunkte Zustandsvariable Typ der Zustandsvariablen mit den Konstanten z0, z1 Die gewählten Punkte werden gespeichert. Sind alle für die Figur notwendigen Punkte bestimmt, wird sie gezeichnet.

11 OOP: Vererbung 11 Implementierung procedure TGUI.AuswahlBoxClick(...); begin if Zustand = z0 then begin case AusWahlBox.ItemIndex of 0,1 : NMax := 2; 2 : NMax := einlesen end; zustand := z1; end; Figur auswählen im Zustand Z0 Procedure TGUI.FormMouseDown(...,X,Y:Integer); Var nr : integer; begin if Zustand = z1 then begin // neuen Punkt dem Array hinzufügen nr := length(Punkte); //Punktzahl feststellen setLength(Punkte,nr+1); //Arraylänge erhöhen Punkte[nr] := Point(x,y); //Punkte zuweisen if nr = NMax-1 then // letzter Punkt? begin zeichneFigur; //Zustand z0 wiederherstellen Punkte := nil; //Punkte löschen Auswahlbox.ItemIndex := -1; Zustand := z0; end; Punkte speichern im Zustand Z1

12 OOP: Vererbung 12 Teil 2 Projekt Minigolf

13 OOP: Vererbung 13 Minigolfanlage Start Ziel Ziel: Ball ins Loch schlagen

14 OOP: Vererbung 14 Modellierung der Animation Benutzer klickt aufs Spielfeld Ball rollt schrittweise in Richtung der Verbindungslinie Maus – Ballmitte Bei jedem Schritt wird seine Geschwindigkeit geringer Spielende, wenn Zielpunkt erreicht Lösung: - Animationsschritte – timergesteuert (Ereignis: OnTimer) - Vermeidung von Flimmern durch Doppelte Pufferung Idee: Doppelte Pufferung – Double Buffering: Zusätzlich zum Bild auf dem Monitor wird noch ein Bild im Hintergrund gehalten. Hierzu wird ein zweites Canvas-Objekt für das Bild im Speicher benötigt. Alle graphischen Ausgaben erfolgen zunächst im Speicherbild; anschließend wird dieses auf dem Monitor ausgegeben. Doppelte Pufferung – Double Buffering: Zusätzlich zum Bild auf dem Monitor wird noch ein Bild im Hintergrund gehalten. Hierzu wird ein zweites Canvas-Objekt für das Bild im Speicher benötigt. Alle graphischen Ausgaben erfolgen zunächst im Speicherbild; anschließend wird dieses auf dem Monitor ausgegeben.

15 OOP: Vererbung 15 OOA: Analyse GUI Puffer Ball KZiel KStart Bitmap-Objekt Formular Kreisobjekte Fachkonzept GUI-Schicht Steuerung TimerAnimator SpielfeldImage-Komponente

16 OOP: Vererbung 16 Beziehungen TBall TForm TImage TKreis TCanvas TGUI 1 benutzt ist ein 2 1 TTimer Fachkonzept GUI-Schicht TBitmap 1

17 OOP: Vererbung 17 Modellierung der Klassen TKreis xPos, yPos //Mittelpunkt FFarbe, FRad Canvas //Ref. auf Zeichenfläche create paint moveto // an neue Position TBall vx //Geschw. in x - Richtung vy //Geschw. in y – Richtung Zustand (liegt,rollt) rolle //verschieben um vx,vy setV getAbsV getZustand setZustand ist ein KZielKStartBall instance of Klassen: Objekte: instance of

18 OOP: Vererbung 18 Implementierung der Klasse TKreis procedure TKreis.paint; var x1,y1,x2,y2 : integer; begin //umgebendes Rechteck x1 := xPos-Frad; y1 := yPos-Frad; x2 := xPos+Frad; y2 := yPos+Frad; with canvas do begin Pen.Mode := pmNotXor; Pen.Color := clblack; brush.color:= FFarbe; ellipse(x1,y1,x2,y2); end; constructor TKreis.create(CanRef : TCanvas; x,y : integer); begin xPos := x; yPos := y; canvas := CanRef;// Anbindung an GUI end; TKreis - xPos : integer - yPos : integer - FRad : integer - FFarbe : TColor - Canvas : TCanvas + Create(CanRef : TCanvas; x,y : integer) + paint + moveto(x,y : integer) + setAttribute(r : integer; f : TColor) Zeichnen im NotXOR-Modus ermöglicht Löschen der Figur - nicht bei Doppelter Pufferung

19 OOP: Vererbung 19 Implementierung der Klasse TKreis procedure TKreis.setAttribute(r : integer;f : TColor); begin //paint; //zum Löschen FRad := r; FFarbe := f; //paint; //zum Löschen end;; procedure TKreis.moveto(x,y : integer); begin //paint; //zum Löschen xPos := x; yPos := y; //paint;//erneut zeichnen end; TKreis - xPos : integer - yPos : integer - FRad : integer - FFarbe : TColor - Canvas : TCanvas + Create(CanRef : TCanvas; x,y : integer) + paint + moveto(x,y : integer) + setAttribute(r : integer; f : TColor)

20 OOP: Vererbung 20 Implementierung der Klasse TBall type TZustand = (liegt, rollt); TBall = class(TKreis) //abgeleitet von TKreis private vx,vy : double; Zustand : TZustand; public procedure rolle; procedure setV(x, y : double); function getAbsV : double; function getVx : double; function getVy : double; function getZustand : TZustand; procedure setZustand(z : TZustand); end; Vererbung: Die Klasse TKreis wird erweitert; dabei werden die Attribute und Operationen an die abgeleitete Klasse weitergegeben. Vererbung: Die Klasse TKreis wird erweitert; dabei werden die Attribute und Operationen an die abgeleitete Klasse weitergegeben. TBall - vx : double - vy : double; - Zustand: TZustand + rolle; + setV(x, y : double); + getV : double; + getZustand : TZustand + getZustand TKreis ist ein

21 OOP: Vererbung 21 Implementierung der Klasse TBall procedure TBall.setV(x, y : double); begin vx := x; vy := y; if getAbsV > 0.5 then Zustand := rollt else Zustand := liegt; end; function TBall.getAbsV : double; begin result := sqrt(vx*vx + vy*vy); end; procedure TBall.rolle; begin if Zustand = rollt then begin xPos := round(xPos + vx); yPos := round(yPos + vy); setV(0.8*vx, 0.8*vy); end; TBall - vx : double - vy : double; - Zustand : TZustand + rolle; + setV(x, y : double); + getAbsV : double; + getZustand : TZustand + getZustand TKreis ist ein

22 OOP: Vererbung 22 Modellierung des Ballabschlags Der liegende Ball, wird er durch Mausklick (x,y) abgeschlagen. Der Abschlag erfolgt in Richtung des Verbindungslinie Mauspunkt Ballmitte. vx V vy Mausklick: Ball abschlagen Geschwindigkeitsvektor: vx = Ball.getx – x vy = Ball.gety – y Geschwindigkeitsvektor: vx = Ball.getx – x vy = Ball.gety – y Animation-OnTimer: Ball.rolle wird in der Ereignismethode der Timerkomponente ständig ausgerufen. Die Position wird neu berechnet und die Geschwindigkeit verringert. Eine Zustandsänderung (liegt) erfolgt, wenn sie zu klein wird. (x,y)

23 OOP: Vererbung 23 Ball: Zustandsdiagramm Alter ZustandAuslösende AktionAusgelöste AktionNeuer Zustand liegt SpielfeldMouseDownBall.setV(vx,vy) rollt BtnStartPosClickStartposition einnehmen liegt AnimiereBall.rolle liegt rollt Animiere [Im Ziel] [außerhalb] Ball.rolle -> Bewegung [|v| > 0,5]/[|v| < 0,5]rollt/liegt liegt Zustände des Balls liegt v = 0 rollt|v| > 0,5 [|v| > 0,5] SpielFeldMouseDown setV(vx,vy) rollt lieg t [|v|< 0,5] v [im Ziel] v [außerhalb] animiere rolle animiere Rolle animiere rolle

24 OOP: Vererbung 24 Modellierung des Spielablaufs Spielphasen: Sp0 Bahn vorbereitet Sp1Bahn wird bespielt Sp2Bahn beendet Sp3Spiel beendet SpUunterbrochen Anforderungen: Bei Spielbeginn Ball auf Startposition Kein Abschlag, wenn Ball im Loch oder außerhalb des Spielfeldes Bahn/Spiel zu Ende, wenn Ball im Loch Alter Zustand Auslösende AktionAusgelöste Aktionen Neuer Zustand Sp0 SpU BtnStartPosClick Ball auf Startpunkt Ball.setZustand(liegt) Punkte auf 0 Sp1 Ball auf Startpunkt Strafpunkte Sp1 SpielFeldMouseDownBall.setV, Punkte erhöhenSp1 Animiere Ball.rolle [Eingelocht] [außerhalb] [im Locht&[alle Bahnen] Sp1 Sp0 (Sp2) SpU (Sp3) Sp2BtnNextBahnBahn aufbauen/Ball auf BahnSp0

25 OOP: Vererbung 25 Zustandsdiagramm BtnStartPosClick Ball an Start Sp1 Sp 0 BtnStartPosClick Ball an Start Strafpunkte SpielFeldMouseDown Ball.setV(vx,vy) animiere [außerhalb] In der einfachen Version (nur eine Spielbahn) entfallen die Zustände Sp2 und Sp3 Spielablauf: SpU animiere [eingelocht] BtnNextBahn Bahn aufbauen Ball auf Bahn Sp2 Sp3 animiere [eingelocht & alle Bahnen] animiere

26 OOP: Vererbung 26 Doppelte Pufferung 1.Zeichnen im Hintergrund: Puffer.canvas.ellipse(...); 2. Hintergrundbild ins Spielfeld kopieren: Spielfeld.canvas.draw(0,0,Puffer) Spielfeld.canvas Puffer.canvas Graphikausgabe in zwei Schritten: Hintergrundbild Puffer : TBitmap Monitorbild Spielfeld : TImage Bei der Animation von bewegten Objekten wird das Hinter- grundbild vor jeder Änderung gelöscht, indem die Zeichen- fläche mit der Hintergrundfarbe gefüllt wird: Puffer.Canvas.fillRect(...); Bei der Animation von bewegten Objekten wird das Hinter- grundbild vor jeder Änderung gelöscht, indem die Zeichen- fläche mit der Hintergrundfarbe gefüllt wird: Puffer.Canvas.fillRect(...);

27 OOP: Vererbung 27 var Puffer : TBitmap; //enthält das Hintergrundbild procedure TFenster.FormCreate(... ); begin Puffer := TBitmap.Create; Puffer.Width := SpielFeld.Width; Puffer.Height := SpielFeld.Height;... StartPkt := TKreis.create(Puffer.canvas,StartX,StartY); ZielPkt := TKreis.create(Puffer.canvas,400,100); Ball := TBall.create(Puffer.canvas,50,50);... end; Implementierung: Doppelte Pufferung Bitmap-Objekt erzeugen Größe des Puffers anpassen Zeichenfläche des Puffers an Graphik-Objekte übergeben Idee: Alle Graphikausgaben erfolgen zunächst in ein Hintergrundbild, das dann als Ganzes in eine sichtbare Zeichenfläche kopiert wird. Einrichten des Puffers ( OnCreate )

28 OOP: Vererbung 28 procedure TFenster.zeichneSpielFeld; begin //altes Bild löschen (mit Hintergrundfarbe füllen) Puffer.Canvas.Brush.Color := SpielFeld.Canvas.Brush.Color; Puffer.Canvas.FillRect(rect(0,0,Puffer.width,Puffer.height)); //Graphische Objekte neu zeichnen im Hintergrund StartPkt.paint; ZielPkt.paint; Ball.paint; //Hintergrundbild in Zeichenfläche des Spielfeldes kopieren SpielFeld.Canvas.Draw(0,0,Puffer); end; Implementierung: Doppelte Pufferung Hintergrundbild aufbauen und auf dem Monitor ausgeben Die Formular-Methode zeichneSpielfeld enthält alle Graphikbefehle. Sie wird nach jeder Aktualisierung eines Graphikobjekts aufgerufen. Benutzt man das Canvas-Objekt des Formulars als Monitorzeichenfläche, so kann das Zeichnen durch das OnPaint-Ereignis des Formulars ausgelöst werden. Die Formular-Methode zeichneSpielfeld enthält alle Graphikbefehle. Sie wird nach jeder Aktualisierung eines Graphikobjekts aufgerufen. Benutzt man das Canvas-Objekt des Formulars als Monitorzeichenfläche, so kann das Zeichnen durch das OnPaint-Ereignis des Formulars ausgelöst werden.

29 OOP: Vererbung 29 Aufgaben 2 1.Programm Minigolf testen. 2.Programm so erweitern, dass Spielstände angezeigt werden. - pro Schlag ein Punkt - 2 Strafpunkte, wenn Ball von außerhalb zurückgeholt wird 3.Reflexion an den Rändern des Spielfeldes 4.Entwicklung eines magischen Feldes (Objekt), das den Ball vom Spielfeld schleudert, sobald er es betritt.

30 OOP: Vererbung 30 Teil 3 Modellierung grafischer Objekte

31 OOP: Vererbung 31 Anwendungsbeispiel Aktivitäten: verschieben, drehen, skalieren, editieren

32 OOP: Vererbung 32 Anforderungen Erzeugung und Verwaltung von grafischen Objekten unter- schiedlicher Form Fähigkeiten der Objekte -frei verschiebbar (Maus) -skalierbar -drehbar

33 OOP: Vererbung 33 Erste OOA-Analyse Problem: Vielfalt der Objekte Optimierung: Entwicklung einer Klassenhierarchie TKreis TRechteck TParallel TQuadrat TDreieck TText...

34 OOP: Vererbung 34 Klassenhierarchie TGrafikElement TKreisTPolygonTTextTLinie TRegNEck TRechteck TParallel

35 OOP: Vererbung 35 Klassenhierarchie Optimierung der Klassen durch Entwicklung einer Vererbungsstruktur Ziele: Der gemeinsame Kern aller Elemente wird in einer Basisklasse modelliert. Spezialisierte Klassen werden von der Basisklasse abgeleitet; sie fügen spezielle Attribute und Operationen hinzu oder definieren bestimmte Dinge neu.

36 OOP: Vererbung 36 Klassenhierarchie Vorteile: Durch Vererbung werden alle gemeinsamen Eigenschaften und Operationen an abgeleitete Klassen weitergegeben: Grundlegende Attribute und Operationen werden nur einmal entwickelt Möglichkeit zur Anpassung und Erweiterung unter geringem Aufwand (Wiederverwendbarkeit) Einheitlicher Zugriff auf verschiedene Objekttypen wird möglich (Polymorphismus)

37 OOP: Vererbung 37 Einfaches Beispiel Kreise und Rechtecke

38 OOP: Vererbung 38 Kreise und Rechtecke TKreis xPos, yPos //Mittelpunkte FFarbe // Füllfarbe Canvas //Zeichenflächenref. Markiert // Markierungsflag FRad //Radius Create paint Moveto // verschieben skalieren //vergrößern TRechteck xPos, yPos //Mittelpunkte FFarbe // Füllfarbe Canvas //Zeichenflächenref. Markiert // Markierungsflag FBreite, FLaenge Create paint Moveto // verschieben skalieren //vergrößern Beide Klassen besitzen gleiche Attribute und Methoden gleicher Funktionalität. Das Gemeinsame muss nicht mehrmals implementiert werden!

39 OOP: Vererbung 39 Erste Modellierung der Klassen TKreis FRad //Radius paint skalieren //vergrößern TRechteck FBreite, FLaenge paint skalieren //vergrößern Basisklasse abgeleitete Klassen (Unterklasse) Generalisierung Spezialisierung Die Basisklasse enthält den gemeinsamen Kern aller grafischen Objektklassen. TGrafikElement xPos, yPos //Mittelpunkte FFarbe // Füllfarbe Canvas //Zeichenflächenref. Markiert // Markierungsflag Create //Basiskonstruktor Moveto // verschieben ist ein

40 OOP: Vererbung 40 Implementierung der Basisklasse TGrafikElement - xPos : integer - yPos : integer - FFarbe : TColor - Fmarkiert : boolean - Canvas : TCanvas + Create(CanRef : TCanvas; x, y : integer) + moveto(x, y : integer); + getX : integer + getY : integer TGrafikElement = class private xPos : integer; yPos : integer; FFarbe : TColor; Fmarkiert : boolean; Canvas : TCanvas; public constructor create(CanRef : TCanvas; x,y : integer); procedure moveto(x,y : integer); function getX : integer; function getY : integer; getFarbe Farbe : Tcolor; procedure setFarbe(wert : TColor); end;

41 OOP: Vererbung 41 Implementierung der Basisklasse constructor TGrafikElement.create(CanRef : TCanvas; x,y : integer); begin xPos := x; yPos := y; canvas := CanRef; End; TGrafikElement - xPos : integer - yPos : integer - FFarbe : TColor - Fmarkiert : boolean - Canvas : TCanvas + Create(CanRef : TCanvas; x, y : integer) + getX : integer + getY : integer Die Objekte erhalten eine Referenz auf das Zeichenflächenobjekt des GUI-Objekts procedure TGrafikElement.moveto(x,y : integer); begin xPos := x; yPos := y; end;

42 OOP: Vererbung 42 Ist ein - Beziehung Die Unterklassen beschreiben nur die Abweichungen von von der Oberklasse. Alles andere kann wiederverwendet werden, weil es in der Oberklasse vorliegt. Die Methoden und Attribute der Oberklasse bilden eine Teilmenge der Methoden und Attribute der Unterklasse. Ein Objekt der Unterklasse hat somit ein Objekt der Oberklasse als Teilobjekt. Umgekehrt sind alle Objekte der Unterklasse eine Teilmenge der Objekte der Oberklasse. TGrafikElement... TKreis - FRad : integer - setRadius(wert : integer) + paint + setAttribute( r : integer, f : TColor) ist ein Jeder Kreis ist ein GrafikElement Konsequenz : Zuweisungskompatibilität Einer Variablen vom Typ der Oberklasse kann eine Referenz auf ein Unterklassenobjekt zugewiesen werden.

43 OOP: Vererbung 43 Implementierung der Klasse TKreis TKreis = class(TGrafikElement) private Frad : integer; public constructor create(CanRef : TCanvas; x,y : integer); procedure paint; procedure setAttribute(r : integer;f : TColor); function getRadius : integer; procedure setRadius(wert : integer); end; TGrafikElement... TKreis -FRad : integer paint + setAttribute( r : integer, f : TColor) + getRadius : ineger + setRadius(wert : integer) ist ein

44 OOP: Vererbung 44 Implementierung der Klasse TKreis TGrafikElement... TKreis - FRad : integer - setRadius(wert : integer) + paint + setAttribute( r : integer, f : TColor) ist ein constructor TKreis.create(CanRef : TCanvas; x,y : integer); begin inherited create(CanRef,x,y); //Konstruktor der Oberklasse FRad := 10; end; Durch Aufruf des geerbten Konstruktors werden die Attribute des Basisobjekts initialisiert. Das abgeleitete Objekt enthält quasi ein Basisobjekt als Teilobjekt.

45 OOP: Vererbung 45 Implementierung der Klasse TKreis TGrafikElement... TKreis - FRad : integer + paint + setRadius(wert : integer) + setAttribute( r : integer, f : TColor) ist ein procedure TKreis.setAttribute(r : integer;f : TColor); begin FRad := r; FFarbe := f; end; procedure TKreis.paint; var x1,y1,x2,y2 : integer; begin //umgebendes Rechteck x1 := xPos-Frad; y1 := yPos-Frad; x2 := xPos+Frad; y2 := yPos+Frad; with canvas do begin brush.color:= FFarbe; ellipse(x1,y1,x2,y2); end;

46 OOP: Vererbung 46 Vererbung und Zugriffrechte Schutzebenen: public keine Zugriffsbeschränkung nach außen private Zugriff nur innerhalb einer Klasse protected Zugriff auch in abgeleiteten Klassen möglich Elemente einer Klasse können in der Klassendeklaration vor dem Zugriff von außen geschützt werden (Geheimnisprinzip). Vererbung der Zugriffsrechte Die Zugriffsrechte einer Klasse werden an abgeleitete Klassen vererbt. Schutzrechte können in einer abgeleiteten Klasse abgeschwächt, aber nicht verschärft werden. Die Schutzebenen private und protected gelten allerdings nur für den Zugriff aus einer anderen Unit heraus.

47 OOP: Vererbung 47 Zuweisungskompatibilität Konsequenz der ist ein – Beziehung: Einer Objektvariablen einer Oberklasse können Objekte aller Unterklassen zugewiesen werden. Die Umkehrung gilt nicht. Beispiel: Var Kreis : TKreis; Rechteck : TRechteck Grafik : TGrafikElement;... Kreis := TKreis.create(...); Rechteck := TRechteck.create(..);... Beachte: Grafik ist eine Referenz auf den Teil des Kreisobjekts, der von TGrafikElement geerbt wird. Möglich: Grafik := Kreis; Grafik.setFarbe(clred); Grafik := Rechteck; Nicht möglich: Grafik.setAttribute(...) Grafik.setBreite(100);

48 OOP: Vererbung 48 is - Operator : Typprüfung (Laufzeit) Beispiel: Var Figur : TGrafikElement; Kreis : TKreis;... if Figur is TKreis then TKreis(Figur).paint; Typumwandlung (type cast) - liefert true, wenn das Objekt Figur eine Instanz der angegebenen Klasse oder eines ihrer abgeleiteten Klassen ist Operatoren is und as as - Operator : Typumwandlung (Laufzeit) Beispiel: Kreis := Figur as TKreis; (Figur as TKreis).paint; - liefert eine Referenz auf ein Objekt vom des Objektes Kreis

49 OOP: Vererbung 49 Statische Methoden Kreis.paint; //paint - Methode des Kreisobjekts Rechteck.paint; //paint - Methode des Rechteckobjekts Der Typ der Referenz auf das Objekt bestimmt, welche Methode aufgerufen wird. Die bisher definierten Methoden sind statisch: Beim Compilieren ist der Objekttyp bekannt, sodass die Sprungadresse der Methode festgelegt werden kann (statische Bindung) Problem: Dieses Verhalten ist, wenn Vererbung ins Spiel kommt, oft unerwünscht. Z. B. wenn sich erst zur Laufzeit entscheidet, welcher Objekttyp angesprochen wird.

50 OOP: Vererbung 50 Statische Methoden Beispiel: Zur Laufzeit werden verschiedene Grafikobjekte erzeugt und ihre Referenzen in einem Array als Container verwaltet: Var Figur : array[1..10] of GrafikElement; Ziel: Einheitlicher Zugriff auf bestimmte Methoden, wie z. B.: for i := 1 to 10 do Figur[i].paint; Dazu müsste der aktuelle Objekttyp für die Auswahl der Methode maßgebend sein. Da zur Compilierzeit noch nicht feststeht, welche Objekttypen ins Array aufgenommen werden, entscheidet sich erst zur Laufzeit, welche Objektmethode aufgerufen werden soll.

51 OOP: Vererbung 51 Virtuelle Methoden Die Basisklasse erhält ebenfalls eine Methode paint; diese wird aber als virtual deklariert. TGrafikElement = class private... public... procedure paint;virtual; end; TKreis = class(TGrafikElement) private... public procedure paint;override;... end; Lösung des Problems durch virtuelle Methoden: paint wird in der Unterklasse überschrieben, d.h. als override deklariert und neu implementiert.

52 OOP: Vererbung 52 Verhalten virtueller Methoden Var Figur : Array[1..10] of GrafikElement; Figur[5].paint; //Aufruf der virtuellen Methode Die Referenz auf das Objekt enthält Information über den Typ des übergebenen Objekts. Dadurch kann die zum Objekt passende Methode aufgerufen werden. Der Typ des aktuellen Objekts bestimmt zur Laufzeit die Methode. Interne Realisierung: Objekte besitzen einen Zeiger auf eine virtuelle Methodentabelle (VMT), die Zeiger auf alle virtuellen Methoden der Klasse enthält. Bei virtuellen Methoden erfolgt der Aufruf über diese Methodenzeiger-Tabelle. Dynamische Bindung / late binding

53 OOP: Vererbung 53 Polymorphismus Das Konzept der dynamischen Bindung heißt in der OOP Polymorphismus (Vielgestaltigkeit). Merkmale Bei polymorphen Objektenvariablen entscheidet sich erst zur Laufzeit, welcher Klasse das Objekt angehört. Eine in einer Basisklasse als virtual deklarierte Methode definiert eine Schnittstelle für alle abgeleiteten Klassen, auch wenn diese noch nicht festgelegt sind. Ein Programm, das virtuelle Methoden einer Basisklasse enthält kann sehr leicht um abgeleitete Klassen erweitert werden, weil sichergestellt ist, dass stets die richtige Methode aufgerufen wird. Empfehlung Statische Methoden einer Basisklasse sollten nicht überschrieben werden. Wenn Überschreiben notwendig erscheint, sollte die Methode als virtual deklariert werden.

54 OOP: Vererbung 54 Abstrakte Klassen Die Basisklasse TGrafikElement muss die Methode paint enthalten, kann sie aber nicht sinnvoll implementieren, weil diese Klasse zu allgemein ist. Die Implementation kann also entfallen. Dazu wird die virtuelle Methode der Basisklasse zusätzlich als abstract deklariert. Merkmale: Abstrakte Klassen enthalten mindestens eine abstrakte virtuelle Methode, die überschrieben werden muss. Von abstrakten Klassen können keine Instanzen gebildet werden. Abstrakte Klasse bilden eine gemeinsame Schnittstelle für alle Unterklassen. TGrafikElement = class... procedure paint;virtual;abstract;... end; TGrafikElement als abstrakte Klasse

55 OOP: Vererbung 55 Aufgaben 3 1.Programm SimpelObjekt testen 2.Ergänzung der Objekte um die Funktion Flaeche. Der Zugriff soll polymorph erfolgen. 3.Ableitung der Klasse TQuadrat von TRechteck und testen 4.Polymorphismus anwenden: Eine Bank verfügt über Girokonten und Sparkonten. Während Girokonten überzogen werden können, dürfen Sparkonten keinen negativen Stand aufweisen. Der Auszahlungsaufruf soll für beide Kontotypen einheitlich sein Entwickeln Sie eine geeignete Vererbungsstruktur (UML)

56 OOP: Vererbung 56 Teil 4 Objektverwaltung

57 OOP: Vererbung 57 Objektverwaltung Aufgaben eines Objektverwalters Referenzen unterschiedlicher Objekttypen speichern Einfügen, entfernen von Referenzen Zugriff auf einzelne Objekte oder alle ermöglichen Zeichnen aller Objekte Realisierung Speicher (lineare Liste) Array of TGrafikElement (dyn. Array) Lineare Liste entwickeln Vorhandene Container – Objekte nutzen oder anpassen (TList) Methoden Einfügen Entfernen Verschieben (innerhalb der Liste) Objekt an bestimmter Position ermitteln Zeichnen

58 OOP: Vererbung 58 Klassendiagramm TGrafikElement #F Markiert : boolean; #Farbe : Tcolor xPos : integer yPos : integer # zeichneMarke + paint TVerwalter - Elemente : TList + Count : integer + add(Objekt : TGrafikElement) + getElement( index : integer); + getElementAt(x, y : integer) : TGrafikElement + entferne(Objekt : TGrafikElement) + paintAll * TGUI SelObjekt : TGrafikElement Verwalter : TVerwalter FormCreate(...) FormPaint(...) FormMouseDown(...) FormMouseMove(...) Der Verwalter hat ein Tlist- Objekt zur Aufnahme der Elemente 1 getElementAt(x,y) - Element an der Position (x, y) der Zeichenfläche

59 OOP: Vererbung 59 Problem: Objekt auswählen function TVerwalter.getElementAt(x, y : integer): TGrafikElement; var i, dx, dy : integer; Obj : TGrafikElement; begin result := nil; for i := 0 to Elemente.Count-1 do begin Obj := TGrafikElement(Elemente[i]); dx := x-Obj.getx; dy := y-Obj.gety; if dx*dx + dy*dy < 100 then result := Obj; end; Liste der Objekte durchlaufen und Abstand zum übergebenen Punkt (x,y) berechnen Abstandsbedingung prüfen Referenz des letzten gefundenen Objekts zurückgeben evtl. gefundenes Objekt ans Ende der Liste setzen, damit es als letztes gezeichnet wird und damit alle anderen überdeckt. Objekt an der Stelle (x, y) Algorithmus:

60 OOP: Vererbung 60 Zusammenfassung 1. Optimierung der Klassenstruktur Verwaltungs - Klassen hinzufügen Komplexe Klassen zerlegen 2. Optimierung der Attribute 3. Optimierung der Operationen 4. Optimierung der Vererbungsstruktur Abstrakte Operationen für einheitliche Schnittstellen Abstrakte Oberklassen bilden Polymorphismus maximieren Vererbungshierarchie komprimieren Existierende Klassen wiederverwenden OOD- Klassendiagramm

61 OOP: Vererbung 61 Aufgaben 4 Erweiterung des Programms SimpelObjekt Objektverwalter einbinden (Klasse TVerwalter (Unit: uVerwalter) Objekte mit der Maus über den Bildschirm ziehen Farbe oder Größe einer mit Maus gewählten Figur ändern Mit Hilfe der Maus beliebig viele Objekte interaktiv erzeugen

62 OOP: Vererbung 62 Teil 5 Realisierung des Tangram-Projekts

63 OOP: Vererbung 63 Anforderungen Erzeugung geometrischer Objekte Beschränkung auf Polygone und Kreise genügt Fähigkeiten der Objekte -verschiebbar (Maus) -skalierbar -Drehbar Verwaltung der Objekte mit Hilfe eines Verwalter-Objekts

64 OOP: Vererbung 64 Darstellung eines Polygons Canvas – Methode: procedure Polygon(Points array of TPoint) Der Parameter ist ein beliebig langes Array (dyn. Array) von Punkten (TPoint). Die Punkte enthalten die Bildschirmkoordinaten der Eckepunkte der Figur. Canvas – Methode: procedure Polygon(Points array of TPoint) Der Parameter ist ein beliebig langes Array (dyn. Array) von Punkten (TPoint). Die Punkte enthalten die Bildschirmkoordinaten der Eckepunkte der Figur. Problem: - Der Referenzpunkt (xPos,yPos) soll Mittelpunkt der Figur sein. (erleichtert Drehen und Verschieben) - Die Figur soll um den Referenzpunkt gedreht werden. Lösung: Die aktuellen Bildschirmkoordinaten werden stets aus einem Basispolygon berechnet, dessen Mittelpunkt der Ursprung (0,0) ist. Alle Manipulationen (Vergrößerung, Verschiebung, Drehung) werden nur am Basispolygon durchgeführt und dieses anschließend zum Referenzpunkt verschoben.

65 OOP: Vererbung 65 Optimierte Klassen Reduzierung auf die Klassen TKreis und TPolygon TGrafikElement # Markiert : boolean;... # zeichneMarke + paint + moveto(x,y :integer) + skaliere(k : double) TPolygon + initPolygon(... ); + paint + skaliere(k : double) + rotate(alpha : double) # SPunkte : Array of TPoint # BPunkte : array of TPunkt TKreis + paint; + skaliere(k : double) TGrafikVerwalter + add(Element : TObjekt) + getElement( index : integer); + getElementAt(x, y : integer) : TGrafikElement 1 * abstrakt

66 OOP: Vererbung 66 Deklaration der Klasse TPolygon TPolygon = class(TGrafikElement) protected Fn : integer; //Anzahl der Ecken SPunkte : array of TPoint; //aktuelle Bildschirmkoordinaten der Eckpunkte BPunkte : array of TPunkt; //Basispunkte (logische Koordinaten) procedure setSchwerpunkt(absolut : boolean); //Schwerpunkt als Mittelpunkt procedure zumRefPunkt; //Bildschirmkoordinaten der EckPunkte aktualisieren public procedure initPolygon(p : array of TPunkt; absolut : boolean);virtual; procedure paint;override; procedure moveto(x,y : integer);override; procedure skaliere(k : double);override; procedure rotate(alpha : double);virtual; function n : integer; end;

67 OOP: Vererbung 67 Klasse TPolygon TPolygon + initPolygon(... ); + paint + skaliere(k : double) + rotate(alpha : double) # SPunkte : array of TPoint # BPunkte : array of TPunkt Initialisierung: initPolygon(p : array of TPunkt; absolut : boolean) - übernimmt ein Punkte-Array und bildet daraus das Basispolygon. - absolut : gibt an, ob die Koordinaten absolute Bildschirmkoordinaten sind Type TPoint = record x,y : integer end; TPunkt = record x,y : double end; Umwandlungsfunktionen function Point(x, y : Integer): TPoint; function Punkt(x, y : double) : TPunkt;

68 OOP: Vererbung 68 Initialisieren des Basispolygons Schritte: 1.Initialisieren der dynamischen Arrays SPunkte und BPunkte 2.Speichern der übergebenen Punkte in Bpunkte 3.Polygon so verschieben dass der Ursprung zum Schwerpunkt wird 4.Zum Referenzpunkt schieben, d. h. SPunkte bestimmen procedure TPolygon.setPolygon(p : array of TPunkt; absolut : boolean); //Basispolygon initialisieren var i : integer; begin Fn := Length(p); //Anzahl der Punkte ermitteln und speichern setLength(BPunkte,Fn); //dyn. Array mit Fn Werten initialisieren setLength(SPunkte,Fn); for i := 0 to Fn-1 do // Punkte in BPunkte speichern BPunkte[i] := p[i]; setSchwerpunkt(absolut); zumRefPunkt; // SPunkte aktualisieren end;

69 OOP: Vererbung 69 Schwerpunkt setzen procedure TPolygon.setSchwerpunkt(absolut : boolean); var i : integer; xs,ys : double; begin //Schwerpunkt des Basispolygons xs := 0; ys := 0; for i := 0 to Fn-1 do begin xs := xs + BPunkte[i].x; ys := ys + BPunkte[i].y; end; xs := xs/n; ys := ys/n; //Basispolygon so verschieben, dass der Schwerpunkt der Ursprung (0;0) wird for i := 0 to n-1 do begin BPunkte[i].x := BPunkte[i].x - xs; BPunkte[i].y := BPunkte[i].y - ys; end; if absolut then begin //Schwerpunkt wird Referenzpunkt xPos := round(xs); yPos := round(ys); end;

70 OOP: Vererbung 70 Verschieben des Basispolygons O BP 1 BP 0 BP 3 BP 2 P0P0 P3P3 P2P2 P1P1 M Für alle Punkte: P.x := xPos + BP.x; P.y := yPos + BP.y; Verschiebung des Basispolygons zum Referenzpunkt BP : Basispunkte P : Bildschirmpunkte Procedure TPolygon.ZumRefPkt

71 OOP: Vererbung 71 Skalieren des Basispolygons Zentrische Streckung des Basispolygons BP 0 BP 1 BP 2 BP 3 BP 0 BP 1 BP 2 BP 3 Für alle Punkte: BP.x := k*BP.x; BP.y := k*BP.y; BP : Basispunkte k : Streckfaktor Procedure skaliere(k : double)

72 OOP: Vererbung 72 Drehen des Basispolygons Drehung eines Punktes um den Ursprung mit Drehwinkel durch Multiplikation mit der Drehmatrix procedure TPolygon.rotate(alpha : double); Var i : integer; x,y : double; begin alpha := alpha*Pi180; for i := 0 to Fn-1 do begin x := cos(alpha)*BPunkte[i].x-sin(alpha)*BPunkte[i].y; y := sin(alpha)*BPunkte[i].x+cos(alpha)*BPunkte[i].y; BPunkte[i].x := x; BPunkte[i].y := y; end; zumRefPunkt; end;

73 OOP: Vererbung 73 Zeichnen des Polygons procedure TPolygon.paint; begin with canvas do begin Pen.Style := pssolid; // Pen.Mode := pmNotXor; Pen.Color := clblack; brush.color := FFarbe; //Polygon zeichnen polygon(SPunkte); if Fmarkiert then zeichneMarke; //Markierungsrechteck end;

74 OOP: Vererbung 74 Anbindung an die GUI-Klasse TGUI Figur : array[1..7] of TGrafikElement SelObjekt : TPolygon FormCreate(...) FormPaint(...) FormMouseDown(...) FormMouseMove(...) TForm ist ein - Verwalter - Objekte erzeugen, Referenzen speichern Ereignisgesteuerter Ablauf: - Objekt auswählen, drehen - Objekt verschieben - ausgewähltes Objekt - Objekte zeichnen

75 OOP: Vererbung 75 Aufgaben 5 1.In der Unit uGrafEleCont ist ein Graphikverwalter(Container) als Ableitung der Klasse TList implementiert. Binden Sie diesen Verwalter in das Tangram-Projekt ein. 2.Leiten Sie die Klasse TLinie für eine Strecke zwischen zwei Punkten TPolygon ab und fügen Sie sie ins Projekt A5/GrafikObjTest ein.

76 OOP: Vererbung 76 Ausblicke Dialogfensters zum Editieren einzelner Objekte Listenfenster zur Ansicht aller Objekte...

77 OOP: Vererbung 77 Dialogfenster Das Dialogfenster ist durch eine Referenz mit einem Objekt verbunden (initialisieren); es somit dessen Operationen aufrufen Aktualisieren liest die Attribute des Objekts und zeigt sie an Speichern schreibt die geänderten Attributwerte ins Objekt zurück TForm TGrafEleDlg Initialisieren() Aktualisieren() Speichern() TGrafikElement

78 OOP: Vererbung 78 Implementierung Var Grafik : TGrafikElement; procedure TGrafEleDlg.init(GrafObj : TGrafikElement); begin Grafik := GrafObj; aktualisiere; end; SelObjekt := getElementAt(x,y); //angeklickte Figur finden if (SelObjekt <> nil) then begin //Dialog öffnen und initialisieren GrafEleDlg.init(SelObjekt);//Referenz übergeben GrafEleDlg.Show; end; Öffnen des Dialogs im Formular Initialisieren des Dialogs

79 OOP: Vererbung 79 Aufgabe 6 1.Entwerfen Sie einen Editier- Dialog für das Projekt SimpelObjekt 2.Binden Sie den Dialog ins Projekt ein

80 OOP: Vererbung 80 Literatur und Links Helmut Balzert: Lehrbuch der Software-Technik Eckart Modrow: Informatik mit Delphi Band 1 / 2 Siegfried Spolwig: Klaus Merkert

81 OOP: Vererbung 81 Lösung: A 3.4 TKonto - FKontoNr : integer - FStand : double Create (nr : integer) Auszahlen(Betrag : double) TSparkonto + Auszahlen(...) TGirokonto + Auszahlen(...)

82 OOP: Vererbung 82 Projekt Memory Zu entwickeln ist ein Programm, das das bekannte Memory-Spiel simuliert. /0/ In einer ersten Version spielt ein Spieler alleine. Durch Mausklick können die Spielkarten aufgedeckt werden. Der Computer ist dabei der Spielleiter. Der Punktestand des Spieler wird protokolliert /1/ In der zweiten Version ist der Computer ein Gegenspieler, der mit einer Gewinnstrategie ausgestattet ist. /0/ In einer ersten Version spielt ein Spieler alleine. Durch Mausklick können die Spielkarten aufgedeckt werden. Der Computer ist dabei der Spielleiter. Der Punktestand des Spieler wird protokolliert /1/ In der zweiten Version ist der Computer ein Gegenspieler, der mit einer Gewinnstrategie ausgestattet ist. Pflichten : Prototyp :

83 OOP: Vererbung 83 Projekt Uhr

84 OOP: Vererbung 84 Ampelsteuerung Fußgängerübergang Nach:

85 OOP: Vererbung 85 Ampelsteuerung Baustelle Nach:


Herunterladen ppt "Vererbung Helmut Paulus Speyer, 7./8.11.2006. OOP: Vererbung 2 Teil 1 Grafik mit Delphi."

Ähnliche Präsentationen


Google-Anzeigen