Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Generische Klasse - ich erhalte einen abstract Fehler... (https://www.delphipraxis.net/186927-generische-klasse-ich-erhalte-einen-abstract-fehler.html)

ADelph 13. Okt 2015 11:57

Generische Klasse - ich erhalte einen abstract Fehler...
 
Hallo,

ich versuche mich etwas intensiver mit generischen Klassen. Dazu habe ich mir folgendes Beispiel erstellt:

Delphi-Quellcode:
program MyProject;

{$R *.res}

uses
  System.SysUtils,
  System.Generics.Defaults,
  System.Generics.Collections,
  MyUnit in 'MyUnit.pas';

type
 TMyNewObj<T> = class(TMyObj<T>)
 private
  procedure MyUsedProc; virtual;
 end;

 TMyNew = class(TMyNewObj<double>)
// private
//  procedure MyUsedProc; virtual;
 end;

var
 MyNewObj : TMyNew;

{ TMyNewObj<T> }

procedure TMyNewObj<T>.MyUsedProc;
begin
 writeln('Hello MyNewObj<T>');
 writeln(FValInt.ToString);
 readln;
end;

//{ TMyNew }
//
//procedure TMyNew.MyUsedProc;
//begin
// writeln('Hello MyNew');
// writeln(FValInt.ToString);
// writeln(Format('%0.2f',[FVal]));
// readln;
//end;

begin
 try
  { TODO -oUser -cConsole Main : Code hier einfügen }
  MyNewObj:=TMyNew.Create;
  MyNewObj.Val:=1.2345;
  MyNewObj.MyUseTheUsedProc;  //<- Hier kommt der Fehler, bzw. ...siehe weiter unten...in MyUnit
 except
  on E: Exception do
   Writeln(E.ClassName, ': ', E.Message);
 end;
 FreeAndNil(MyNewObj);
end.
Delphi-Quellcode:
unit MyUnit;

interface
uses
  System.SysUtils,
  System.Generics.Defaults,
  System.Generics.Collections;

type
 TMyObj<T> = class(TObject)
 private
  FVal   : T;
  FValInt : integer;
  procedure MyUsedProc; virtual; abstract;
 public
  procedure MyUseTheUsedProc;
  property Val: T read FVal write FVal;
 end;

implementation

{ TMyObj<T> }

procedure TMyObj<T>.MyUseTheUsedProc;
begin
 MyUsedProc; //Hier kommt der Fehler dann...
end;

end.
Wenn ich MyNewObj.MyUseTheUsedProc aufrufe erhalte ich die Meldung 'Abstracter Fehler'. Es wird also die in TMyNewObj Prozedur MyUsedProc nicht aufgerufen, sondern die ursprüngliche - und das verstehe ich im Augenblick nicht.

Wo denke ich da falsch? Ich würde das gern verstehen...aber vielleicht verstehe ich das Konzept der generischen Klassen etc. noch nicht richtig...

Auskommentiert habe ich meine weiteren Versuche, bzw. ich würde gern mit der Definition TMyNew arbeiten - aber das klappt auch nicht...

FVal und FValInt sind nur so zum Testen enthalten, damit 'etwas mehr' da ist. Dass ich mit dem Typ 'double' probiere ist auch nur so zum Testen da - hat keinen tieferen Sinn.

Aviator 13. Okt 2015 12:38

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Hi,
bei abgeleiteten Klassen solltest du eine virtuelle Procedure auch überschreiben. Siehe Beispiel unten. Dann müsste es eigentlich funktionieren.

Delphi-Quellcode:
type
  TMyNewObj<T> = class(TMyObj<T>)
  private
    procedure MyUsedProc; override; // <--- Ändere mal das virtual in override
  end;

ADelph 13. Okt 2015 13:00

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Hi,

...da kommt die Meldung:
[dcc32 Fehler] MyProject.dpr(14): E2137 Methode 'MyUsedProc' nicht in Basisklasse gefunden.

Liegt wohl daran, das MyUsedProd als 'abstract' definiert ist.

FaTaLGuiLLoTiNe 13. Okt 2015 13:13

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
MyUsedProc darf nicht private sein, sonst kann sie von der abgeleiteten Klasse nicht gesehen werden.

ADelph 13. Okt 2015 14:00

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
...yo...public und override...wobei ich override nicht verstehe, denn es ist eine abstrakte Methode...

Danke für die Hinweise!

Zacherl 13. Okt 2015 14:54

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Um genau zu sein, solltest du die Methode protected deklarieren (ausgehend davon, dass du sie ursprünglich private haben wolltest).

Warum verstehst du das override im Zusammenhang mit abstrakten Methoden nicht? Eine abstrakte Methode ist einfach eine Methode, die in der Basisklasse zwar deklariert, nicht aber implementiert wird.

Die Implementierung obliegt somit den abgeleiteten Klassen. Dass du explizit noch override angeben musst, ist in diesem Falle ganz normal. Dadurch weiß der Compiler, dass du tatsächlich die abstrakte Methode implementieren/überschreiben und nicht etwa verdecken willst.

ADelph 13. Okt 2015 15:11

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Zitat:

Zitat von Zacherl (Beitrag 1318565)
Warum verstehst du das override im Zusammenhang mit abstrakten Methoden nicht? Eine abstrakte Methode ist einfach eine Methode, die in der Basisklasse zwar deklariert, nicht aber implementiert wird.

...ich hatte irgendwie das Bild, dass dann die Methode auch gar nicht als z.B. Adresse existiert und damit dann auch nicht überschrieben werden müsste...aber das war wohl eine zu bildliche Vorstellung...

...Danke für die Hinweise - hilft mir weiter!

...und habe es jetzt hoffentlich verinnerlicht... ;-)

Zacherl 13. Okt 2015 15:42

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Abstrakte Methoden müssen immer auch als virtual (bzw. dynamic) deklariert werden. Dadurch legt Delphi dann auch einen Eintrag in der Virtual Method Table der Klasse an. Dieser Eintrag zeigt dank des abstract Keywords erstmal auf eine generische Funktion, die nichts macht, außer den Abstract-Error zu schmeißen, den du ja schon kennengelernt hast :D

Erst durch überschreiben ersetzt du den Zeiger in der VTable durch deine eigene Methode in der abgeleiteten Klasse.

ADelph 13. Okt 2015 15:59

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
...jo, das ist mir jetzt auch klar geworden...das kommt davon, wenn ich mich auf meine naive, bildliche Vorstellung verlasse :roll: ...wer genau hinsieht ist klar im Vorteil :wink:

...peinlich ist eher noch, dass ich das in der Vergangenheit schon genutzt habe, wie ich gerade gesehen hab...:oops: ...das Alter...:wink:

Danke für den Anstupser :thumb:

Dejan Vu 14. Okt 2015 06:44

AW: Generische Klasse - ich erhalte einen abstract Fehler...
 
Wieso muss eine abstrakte Methode eigentlich auch als 'virtual' deklariert werden? Gibt es abstrakte Methoden, die nicht virtuell sind? Eigentlich müsste der Compiler doch so klug sein, um sich das 'virtual' bei einem 'abstract' auch denken zu können, oder?


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:18 Uhr.
Seite 1 von 2  1 2      

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