![]() |
Hallo Motzi,
Deine Ausarbeitung beschreibt den Punkt Polymorphie nicht ganz richtig. Das Polymorphie mit "Vielgestaltigkeit" übersetzt werden kann ist richtig. Was Du in Deiner Ausarbeitung unter Polymorphie beschreibst ist eher überschreiben o. ersetzten von Methoden und Eigenschaften. Unter Polymorphie versteht man folgendes: Schaun wir erstmal folgenden Source an
Delphi-Quellcode:
TAbstractBaseClass ist unsere abstrake Basisklasse. Von dieser Klasse werden TFirstClass und TSecondClass abgeleitet. Erst in den Nachfahren wird die procedure DoShowMessage tatsächlich deklariert.
Type
TAbstractBaseClass = class(TObject) private public procedure DoShowMessage; virtual; abstract; end; TFirstClass = class(TAbstractBaseClass) private public procedure DoShowMessage; override; end; TSecondClass = class(TAbstractBaseClass) private public procedure DoShowMessage; override; end; ... procedure TFirstClass.DoShowMessage; begin ShowMessage('TFirstClass'); end; procedure TSecondClass.DoShowMessage; begin ShowMessage('TSecondClass'); end; ... procedure DoIt; var F : TAbstractBaseClass; S : TAbstractBaseClass; begin F:=TFirstClass.Create; // <- hier ist die Polymorphie !!! S:=TSecondClass.Create; // <- hier ist die Polymorphie !!! Try Finally F.Free; S.Free; end; end; In der procedure DoIt werden jetzt die Instanzen F und S vom Type TAbstractBaseClass deklariert. Und jetzt kommt es: F wird als TFirstClass und S als TSecondClass erzeugt. Die Instanzen F und S vom Type TAbstractBaseClass können hier sowohl vom Type TFirstClass oder TSecondClass gestalt annehmen. Das ist Polymorphie. Dadurch, dass in TAbstractBaseClass die Methode DoShowMessage als virtual erklärt wurde wird sie beim Create mit in die Virtuelle Methoden Tabelle (VMT) aufgenommen. Dadurch, das für jede Instanz beim Create eine eigene VMT erzeugt wird, ist sichergestellt, dass immer die richtige DoShowMessage Methode aufgerufen wird. |
Also , die Units sehen bei mir so aus . Falls daran im Aufbau was falsch ist , bitte korrigiert mich .
mFigur(Basisklasse) :
Delphi-Quellcode:
mPlanet :
unit mFigur;
interface uses mSum; type TFigur = class hatpen : buntstift; zXpos,zYpos,zGeschw,zRadius,zAbstand : Zahl; zFarbe : GanzeZahl; constructor init(pXpos,pYpos,pGeschw,pRadius,pAbstand : Zahl;pFarbe : GanzeZahl);virtual; procedure zeichne; procedure loesche; procedure bewege;virtual;abstract; destructor gibfrei; end; implementation constructor TFigur.init(pXpos,pYpos,pGeschw,pRadius,pAbstand : Zahl;pFarbe : GanzeZahl); BEGIN hatpen := buntstift.init; zXpos := pXpos; zYpos := pYpos; zGeschw := pGeschw; zRadius := pRadius; zAbstand := pAbstand; zFarbe := pFarbe; //erste Anweisungen hatpen.setzeFarbe(zFarbe); hatpen.setzeFuellMuster(gefuellt); hatpen.hoch; hatpen.bewegeBis(zXpos,zYpos); END; procedure TFigur.zeichne; BEGIN hatpen.zeichneKreis(zRadius); END; procedure TFigur.loesche; BEGIN zeichne; hatpen.radiere; zeichne; hatpen.normal; END; destructor TFigur.gibfrei; BEGIN hatpen.gibFrei; END; end.
Delphi-Quellcode:
mSonne :
unit mPlanet;
interface uses mSum,mFigur,mSonne; type TPlanet = class(TFigur) zJahr : Zahl; kSonne : TSonne; constructor init(pkSonne : TSonne;pAbstand,pGeschw,pRadius : Zahl;pFarbe: GanzeZahl);overload; procedure bewege;override; end; implementation constructor TPlanet.init(pkSonne : TSonne;pAbstand,pGeschw,pRadius : Zahl;pFarbe: GanzeZahl); BEGIN hatpen := buntstift.init; kSonne := pkSonne; zAbstand := pAbstand; zGeschw := pGeschw; zFarbe := pFarbe; zRadius := pRadius; zXpos := kSonne.zXpos; zYpos := kSonne.zYpos; hatpen.setzeFarbe(zFarbe); hatpen.setzeFuellMuster(gefuellt); hatpen.hoch; hatpen.bewegeBis(zXpos,zYpos); END; procedure TPlanet.bewege; BEGIN hatpen.bewegeUm(zAbstand); inherited zeichne; warte(10); inherited loesche; hatpen.bewegeUm(-zAbstand); hatpen.dreheUm(zGeschw); IF (hatpen.winkel = 360) OR (hatpen.winkel = 0 ) then zJahr := zJahr + 1 ; END; end.
Delphi-Quellcode:
[edit=Daniel B]Delphi-Tags eingefügt. MfG Daniel B.[/edit]
unit mSonne;
interface uses mSum,mFigur; type TSonne = class(TFigur) constructor init(pXpos,pYpos,pRadius : Zahl;pFarbe : GanzeZahl);overload; procedure bewege;override; end; implementation constructor TSonne.init(pXpos,pYpos,pRadius : Zahl;pFarbe : GanzeZahl); BEGIN hatpen := buntstift.init; zXPos := pXpos; zYpos := pYpos; zRadius := pRadius; zFarbe := pFarbe; hatpen.setzeFarbe(zFarbe); hatpen.setzeFuellMuster(gefuellt); hatpen.hoch; hatpen.bewegeBis(zXpos,zYpos); END; procedure TSonne.bewege; BEGIN inherited zeichne; END; end. |
Hallo galaxy2k,
am 14.06.03 habe ich weiter oben etwas zum Thema constructor und destructor geschrieben. Das solltest Du unbedingt beachten !!! Hinweis: Man muß nicht alle Properties über der constructor setzen. Du kannst die Paramter auch als Properties deklarieren und setzen nach dem Du das Objekt erzeugt hast. |
@Jens Schumann: Wenn du dir mal den constructor von TObject anschaust, dann wirst du sehen, dass dieser nur aus einem leeren Funktions-Rumpf besteht, also eigentlich nur ein Dummy-Existenz fristet. Sofern ein Objekt also nur von TObjekt abgeleitet ist, ist ein Aufruf von inherited nicht wirklich notwendig! In den meisten(!) andren Fällen jedoch schon (aber auch nicht immer)!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz