Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kind as Opa innerhalb der Deklerartion (https://www.delphipraxis.net/139971-kind-opa-innerhalb-der-deklerartion.html)

dmdjt 9. Sep 2009 12:26


Kind as Opa innerhalb der Deklerartion
 
Gibt es eine Möglichkeit eine Methode von Großvater bis Kind zu vererben... allerdings beim Kind die Methode vom Großvater direkt aufzurufen?

Hört sich vielleicht etwas konfus an, also hier der Code wie ich es gerne hätte:

Delphi-Quellcode:
procedure TOpa.tuwas;
begin
  showmessage('Opa');
end;


procedure TVater.tuwas;
begin
  showmessage('Vater');
end;

procedure TKind.tuwas;
begin
 (self as TOpa).tuwas;
end;
Also bei mir kommt dann ein StackOverflow. Das würde ich gerne besser verstehen. Erwartet hätte ich vielleicht eine Zugriffsverletzung oder was anderes... aber StackOverflow verweundert mich schon ein wenig.

ChrisE 9. Sep 2009 12:58

Re: Kind as Opa innerhalb der Deklerartion
 
Hallo,

sag mal wie die Klassenherachie aufgebaut ist?
Wie ist tuwas Deklariert (in der abstrakten Basis-Klasse)?

Namenloser 9. Sep 2009 13:06

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von dmdjt
Also bei mir kommt dann ein StackOverflow. Das würde ich gerne besser verstehen. Erwartet hätte ich vielleicht eine Zugriffsverletzung oder was anderes... aber StackOverflow verweundert mich schon ein wenig.

Das macht schon Sinn, wenn du die Prozedur TuWas in der Basisklasse als virtual, und inder abgeleiteten als override deklariert hast. Override bewirkt, dass alle Aufrufe dieser Funktion, sowohl aus der abgeleiteten Klasse, als auch aus der Basisklasse auf die neue Version umgeleitet werden. Die Funktion ruft sich also imemr wieder selbst auf, bis der Stack voll ist.

Eine Möglichkeit die Funktion des Opas aufzurufen kenne ich nicht. Wenn es nur um den Vater ginge, ginge es mit inherited.

dmdjt 9. Sep 2009 13:17

Re: Kind as Opa innerhalb der Deklerartion
 
Der sohn ist vom Vater und der Vater vom Opa abgeleitet. Das ganze soll nur ein Beispiel sein und die Methode TuWas gibt nur eine MessageBox mit entweder dem Text 'Opa' (TOpa) oder 'Vater' (TVater) aus. Bei TKind sollte allerdings wieder 'Opa' ausgegeben werden.

procedure Tuwas; ist public deklariert

Mit virtual, abstract usw. (wie heißen diese Schlüsselworte eigentlich?) kenn ich mich nicht mehr besonders gut aus und hab einfach nur herum probiert. Liegt es vielleicht an denen?

Anwendungsbeispiele fallen mir momentan keine ein. Ich habe die Frage nur irgendwo einmal gelesen und dachte, dass man das vielleicht so implementieren könnte. Ich versuche mir OOP nach längerer Abstinz wieder besser ins Gehirn zu hämmern. Was gar nicht so leicht ist, weil mein bisheriges Wissen ein zur Hälfte vergessenes Halbwissen ist.



Der Fehler tritt auch ohne override auf. Egal als was ich die Methode deklariere.

Edit: Wo bleiben meine Marnieren... Herzlichen Dank natürlich!!

Neutral General 9. Sep 2009 13:26

Re: Kind as Opa innerhalb der Deklerartion
 
Hi,

Ich weiß nicht ob das geht.. entspricht evtl auch nicht dem Grundgedanken von OOP. Aber du könntest versuchen:

Delphi-Quellcode:
procedure TKind.tuwas;
begin
 inherited (inherited tuwas);
end;
weiß allerdings nicht ob man inherited doppelt verwenden kann....

Tryer 9. Sep 2009 13:31

Re: Kind as Opa innerhalb der Deklerartion
 
Auch bei TOpa(Kind).tuwas wird immer die überschiebene Methode aufgerufen, welche sich auf diesem Wege selber aufruft -> StackOverflow.
Mit "inherited" kommt man nur bis zu TVater zurück. Da bestände dann die Möglichkeit für "Sauereien" ala
Delphi-Quellcode:
if (Self is TKind) then
  inherited
else
  ShowMessage('Vater');
Damit ruft ein inherited-Aufruf vom Kind über den Vater - Umweg die Opa-Methode auf. Nicht zu empfehlen da unübersichtlich und unflexibel.

Die Möglichkeit das ganze zu umgehen wäre das verdecken der virtuellen Methode von TOpa (-> reintroduce;). Dadurch existieren die Methoden dann "nebeneinander" und der Aufruf gelingt.

MfG,
Dirk

Meflin 9. Sep 2009 13:32

Re: Kind as Opa innerhalb der Deklerartion
 
Im Zweifelsfall musst du eben ein Parent-Feld einführen (und beim Create richtig belegen).

Sowas wie self.parent.parent.TuWas sollte auf jeden Fall gehen :stupid:

dmdjt 9. Sep 2009 13:43

Re: Kind as Opa innerhalb der Deklerartion
 
Delphi-Quellcode:
procedure TKind.tuwas;
begin
inherited (inherited tuwas);
end;
Geht leider nicht...zumindest nicht in der Form: Missing Operator or semicolon.

Ihr habts einen Haufen interessanter Ideen!

Vielen Dank an euch alle!

Tryer 9. Sep 2009 13:47

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von Meflin
Sowas wie self.parent.parent.TuWas sollte auf jeden Fall gehen :stupid:

Wobei das dann nur funktioniert wenn auch eine Instanz von TOpa existiert. Ich denke mal hier geht es eher ums Klassendesign. Die Bezeichnungen Kind/Vater/Opa sind nur etwas ungünstig gewählt.

Der richtige Weg wäre wohl eher eine Methode nicht so zu überschreiben das sie in der nachfolgenden Klasse nicht zu gebrauchen ist, oder noch besser auch TKind von TOpa abzuleiten.

MfG,
Dirk

ChrisE 9. Sep 2009 13:52

Re: Kind as Opa innerhalb der Deklerartion
 
Ich musste es mir auch erst wieder klar machen, aber es ist wie alle es sagen :mrgreen:

StackOverflow ist klar weil:

Wenn du eine Klasse erstellst, werden ja alle Speicherbereich erstellt die so benötigt werden und eben auch die Ein-Sprungpunkte der Methoden der Klasse. Das Ermöglicht ja das LateBinding / SpäteBindung. D.h. erstmal das ja zum Zeitpunkt das Programmschreibens noch nicht klar ist, welche Methoden tatsächlich aufgerufen werden.
Delphi-Quellcode:
var Person: TPerson;
//...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Person.Tuwas;
end;
wird jetzt in Button2click ein Kind erstellt mit
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Person := TKind.Create;
end;
muss ja irgend etwas dafür sorgen, dass bei Button1Click die richtige Methode aufgerufen wird. Wenn du also den Contructor von TKind aufrufst, wird eine Klasse erstellt die Identisch zu TPerson ist und als Einsprungpunkt für TuWas immer die Methode von TKind.Tuwas hat.

Dieser Mechanismus erzeugt jetzt den Stackoverflow, denn egal welchen Typcast du auf Person außerhalb der Klassen anwendest - es wird immer TKind.Tuwas aufgerufen aufgrund des Einsprungpunktes. Das selbe gilt natürlich für innerhalb der Klassen.

Somit kommt es in dein ursprünglicher Aufruf von (Self as TOpa).Tuwas zum Stackoverflow. Es ergibt sich eine Rekursion unendlicher Tiefe und der Stack läuft über wegen der Rücksprungadressen etc.

Ich hoffe das hilft dir etwas beim Verständnis.

Gruß, Chris

[EDIT] 2x Button1Click :pale: [/EDIT]


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz