Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Frage zur Vererbung von Methoden (https://www.delphipraxis.net/199727-frage-zur-vererbung-von-methoden.html)

Captain Albern 15. Feb 2019 08:00

Frage zur Vererbung von Methoden
 
Guten Tag,

erstmal vorab: Mein Code funktioniert schon (nicht der Code unten, das ist ein verkürztes Beispiel), er scheint mir aber unnötig aufwändig zu sein. Ich denke, es gäbe eine einfachere Lösung, wenn ich mich besser auskennen würde. Kennt sich jemand besser aus ? :wink:

Ich verwende eine Klasse "TProjekt", die ein Array von Objekten "TProtoBlock" enthält. Von diesem TProtoBlock ist eine Reihe von anderen Klassen abgeleitet z.B. TBitmapBlock. Es soll diverse Methoden geben, z.B. Draw, die jede Kind-Klasse hat, die also in TProtoBlock vordefiniert sind, allerdings in jeder Kind-Klasse anders implementiert und daher überschrieben werden. Jetzt hätte ich es gerne so, dass man von außen einen beliebigen Block als TProtoBlock, ohne zu beachten, welcher Subtyp es konkret ist, nimmt und die Draw-Methode aufruft (siehe unten Beispiel-Prozedur). Dann wird allerdings nicht die Draw-Methode der Kind-Klasse aufgerufen, sondern die Draw-Methode von TProtoBlock. Diese kann dann die Draw-Methode der Kind-Klasse aufrufen (siehe Beispiel unten). Das ist aber aufwändig, weil ich diese Typprüfung und Auswahl dann in jeder Methode für jede Art von Unterklasse wieder neu so schreiben müsste. Geht es irgendwie automatisch, dass man sagt, die Draw-Methode der Basisklasse soll versteckt sein und es sollen direkt die Methoden Kinder-Klassen aufgerufen werden ?
Man könnte natürlich den Typ auch in der aufrufenden Funktion prüfen und dann (Block as TBitmapBlock).Draw aufrufen, aber das würde den Aufwand nur von innen nach außen verschieben. Ich hoffe, das war nicht zu verworren. Das Beispiel sollte Klarheit schaffen. Vielen Dank im Voraus !

Delphi-Quellcode:
type
  TProtoBlock = class
    procedure Draw;
  end;
  TBitmapBlock = class(TProtoBlock)
    procedure Draw;
  end;
  //..... weitere Unterarten von class(TProtoBlock)
  //.....
  TProject = class
    Blocks : Array of TProtoBlock;
  end;

var
  Project:TProject;

procedure Beispiel;
begin
  Project.Blocks[x]:=TBitmapBlock.Create;
  Project.Blocks[x].Draw;
end;

procedure TProtoBlock.Draw;
begin
  if Self is TBitmapBlock then (Self as TBitmapBlock).Draw;
  if Self is .....andere Arten
  if Self is .....andere Arten
  if Self is .....andere Arten
end;

Klaus01 15. Feb 2019 08:44

AW: Frage zur Vererbung von Methoden
 
Hallo,

TProtoBlock kennt die Kindklassen nicht.

Warum denkst Du, dass hier:
Delphi-Quellcode:
procedure Beispiel;
begin
  Project.Blocks[x]:=TBitmapBlock.Create;
  Project.Blocks[x].Draw;
end;
TProtoBlock.draw aufgerufen wird?

Du könntest auch die draw Methode in TProtoBlocj abstract deklarieren.
Die Kindklassen müssten dann die Mehode draw implementieren.

Grüße
Klaus

Captain Albern 15. Feb 2019 08:54

AW: Frage zur Vererbung von Methoden
 
Danke Klaus, der Hinweis ab "abstract" hat gefehlt. Es funktioniert jetzt so, wie ich es mir vorstelle.

Zu der Frage:
Warum denkst Du, dass hier: ... TProtoBlock.draw aufgerufen wird?

Ich habe Test-Code eingetragen, der mir zeigt, welche Methode aufgerufen wird. Außerdem habe ich den Code mit dem Debugger schrittweise durchlaufen lassen.

Captain Albern 15. Feb 2019 08:57

AW: Frage zur Vererbung von Methoden
 
Für spätere Leser, die vielleicht die gleiche Frage gesucht haben und hier gelandet sind, ich habe folgendes geändert.

In TProtoBlock, die Methode auf abstract gesetzt und aus dem Implementation-Teil entfernt...
Delphi-Quellcode:
procedure Draw(var Dst:TImage);virtual;abstract;
In TBitmapBlock ein override eingefügt. Ohne das gibt es zur Laufzeit einen Fehler...
Delphi-Quellcode:
procedure  Draw(var Dst:TImage);override;
Vielen Dank nochmal für die schnelle Hilfe !

Jumpy 15. Feb 2019 09:40

AW: Frage zur Vererbung von Methoden
 
"Polymorphie" ist meine ich das Stichwort/Prinzip, aus der Objektorientierten Programmierung, das du hier benutzen willst und was du zuletzt herausgefunden hast, ist die Art und Weise, wie man es in Delphi macht/deklariert.

Nur der Vollständigkeit halber, müsste man glaube ich sagen, dass das "abstract" keine Pflicht ist, aber hier wohl Sinn macht. Bei Mehrstufiger Vererbung ist vielleicht in der untersten Ebene eine Methode als abstract+virtual deklariert, in den darüberliegenden dann ggf. als override+(ggf. wieder virtual).
Hoffe ich hab das jetzt richtig beschrieben?

Dennis07 18. Feb 2019 04:36

AW: Frage zur Vererbung von Methoden
 
Zitat:

Zitat von Captain Albern (Beitrag 1425605)
Ohne das gibt es zur Laufzeit einen Fehler...

Kommt immer drauf an. Wenn du eine abstrakte Methode aufrufst, dann ja. Ohne override steht da implizit immer "reintroduce", allerdings wird, anders als beim expliziten "reintroduce" immer eine Wahrnung ausgegeben.
Solltest du also die neu eingeführte Methode anstatt der ursprünglichen aufrufen, bekommst du keine Fehlermeldung. Ein "inherited" ist nebenbei bemerkt auch in so einem Fall möglich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:05 Uhr.

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