Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasse ableiten: Methode überschreiben & Rückgabetyp ändern (https://www.delphipraxis.net/147881-klasse-ableiten-methode-ueberschreiben-rueckgabetyp-aendern.html)

changlee 18. Feb 2010 06:32


Klasse ableiten: Methode überschreiben & Rückgabetyp änd
 
Hallo,

so langsam muss ich mich auch mal mit Vererbung und Polymorphie auseinandersetzen. Leider habe ich ein Problem mit dem Überschreiben einer Funktion.

Ich habe folgende Vorfahrklassen:

Delphi-Quellcode:

  TJob = class(Tobject)
  private
    fId: integer; // eindeutige JobId
  public
    Feedback: integer;
    property Id: integer read fId;
    constructor Create(aParent: TJobList);
    destructor Destroy; override;
  end;

  TJobList = class(TObject)
  private
    fJobs: TList;
  public
    function NewJob: TJob; virtual; // virtual = darf in abgeleiteten Klassen überschrieben werden
    constructor Create;
    destructor Destroy; override;
  end;
Diese möchte ich nun folgendermaßen ableiten:

Delphi-Quellcode:
  TBackupData = record
    Name: string;
    //...
  end;

  TBackupJob = class(TJob)
  private
    fBackupData: TBackupData;
  public
    property BackupData:TBackupData read fBackupData;
    procedure Setup;
  end;


  TBackupList = class(TJobList)
  private
    //..
  public
    function NewJob: TBackupJob; override; // Compiler Fehler: Deklaration von NewJob unterscheidet sich von vorheriger Deklaration
  end;
Überall wo dann in der JobList auf die einzelnen Jobs zugegriffen wird, steht TJob(fJobs[i]).MachWas. Das sollte ja eigentlich kein Problem darstellen, wenn fJobs[i] in diesem Fall kein TJob sondern ein davon abgeleiteter TBackupJob ist, oder?


Wie muss ich es denn machen, um den im Quelltext erwähnten Compilerfehler nicht zu bekommen?

Viele Grüße,
changlee.

mkinzler 18. Feb 2010 06:39

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Zitat:

Das sollte ja eigentlich kein Problem darstellen, wenn fJobs[i] in diesem Fall kein TJob sondern ein davon abgeleiteter TBackupJob ist, oder?
Nein den ein Backupjob ist ja ein Job
(TBackupJob IS-A TJob)
Wenn du beim Ableiten einer Methode deren Signatur änderst, ist das kein Überschreiben (override) sondern Überladen (overload)

webcss 18. Feb 2010 06:39

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Du solltest in der Basisklasse die funktion ohne virtual definieren
Delphi-Quellcode:
...
function NewJob: TJob;
...
in der abgeleiteten Klasse definierst du NewJob einfach neu
Delphi-Quellcode:
...
function NewJob: TBackupJob;
...
und implementierst sie so
Delphi-Quellcode:
function NewJob: TBackupJob;
begin
  Result:= TBackupJob(inherited add);
end;

changlee 18. Feb 2010 07:00

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Danke für die Antworten.

Ich habe jetzt das "vitual" in der Basisklasse weggelassen und NewJob überschrieben.


Aber folgendes verstehe ich nicht ganz:
Zitat:

Zitat von webcss
und implementierst sie so
Delphi-Quellcode:
function NewJob: TBackupJob;
begin
  Result:= TBackupJob(inherited add);
end;

inherited ruft ja in diesem Fall das NewJob der Basisklasse auf und liefert ein TJob zurück. TBackupJob(inherited) würde ich ja verstehen, aber was hat es mit dem "add" auf sich?


//Edit:

hab gerade gemerkt, dass Delphi das "add" auch gar nicht kennt.
Meintest du vielleicht:
Delphi-Quellcode:
function TBackupList.NewJob: TBackupJob;
begin
  result := TBackupJob(inherited NewJob);
end;

webcss 18. Feb 2010 07:11

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Zitat:

Zitat von changlee
hab gerade gemerkt, dass Delphi das "add" auch gar nicht kennt.
Meintest du vielleicht:
Delphi-Quellcode:
function TBackupList.NewJob: TBackupJob;
begin
  result := TBackupJob(inherited NewJob);
end;

Ja, sorry, genauso meinte ich das. Die Gewohnheit... :drunken:
Alternativ kannst Du auch ne generische Liste nehmen, wo der Compiler dann den Typ einflickt.
So sparst Du Dir viel Tipparbeit und TypeCast Fehler.
Geht aber erst ab/mit D9 bzw. FPC 2.4.0.

hoika 18. Feb 2010 07:17

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Hallo,

warum benutzt du nicht reintroduce ?

Delphi-Quellcode:
type
  TClass1 = class
    function GetValue: Integer; virtual;
  end;

  TClass2 = class(TClass1)
    function GetValue: Boolean; reintroduce;
  end;

function TClass1.GetValue: Integer;
begin
  Result:= 1;
end;

function TClass2.GetValue: Boolean;
begin
  Result:= True;
end;

Heiko

changlee 18. Feb 2010 07:41

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
was wäre denn der Unterschied / Vorteil von reintroduce gegnüber einem direkten Überschreiben?
Ehrlich gesagt verstehe ich auch nicht den Sinn der Direktive virtual.
Ich dachte virtual sei nötig, wenn eine Nachfahrklasse die Methode überschreiben dürfen soll. Offenbar geht es ja aber auch ohne virtual. :gruebel:

guinnes 18. Feb 2010 08:01

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Zitat:

Zitat von changlee
Offenbar geht es ja aber auch ohne virtual. :gruebel:

Du hast damit die Methode nicht überschrieben, du hast nur eine Methode eingeführt, die genau so heisst.
Überschriebene Methoden stehen in der Virtuelen Methoden Tabelle, womit es möglich ist, immer die zum Objekttyp passende Methode aufzurufen :
Delphi-Quellcode:
Type
  Klasse1 : Class
    Meth1( Bla : Integer);
  end;

  Klasse2 : Class(Klasse1)
    Meth1 ( Bla : Integer);
  end;

  Procedure TuWas( Obj : Klasse1);
  Begin
    Obj.Meth1(42);
  end;

  Procedure Test;
  begin
    TuWas(InstanzVonKlasse1);// Tut, wie es tuen soll
    TuWas(InstanzVonKlasse2);// Tut nicht, es wird die Methode Meth1 von Klasse1 !! Ausgeführt
  end;
Bei Vererbung :
Delphi-Quellcode:
Type
  Klasse1 : Class
    Meth1( Bla : Integer);Virtual;
  end;

  Klasse2 : Class(Klasse1)
    Meth1 ( Bla : Integer);Override;
  end;

  Procedure TuWas( Obj : Klasse1);
  Begin
    Obj.Meth1(42);
  end;

  Procedure Test;
  begin
    TuWas(InstanzVonKlasse1);// Tut, wie es tuen soll
    TuWas(InstanzVonKlasse2);// Tut wie es tuen soll;
  end;

hoika 18. Feb 2010 08:04

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Hallo,

in #1 stand
Compiler Fehler: Deklaration von NewJob unterscheidet sich von vorheriger Deklaration

Ich wollte zeigen, wie man den Umgehen kann.


Heiko

sx2008 18. Feb 2010 09:25

Re: Klasse ableiten: Methode überschreiben & Rückgabetyp
 
Du solltest deine Klassen so designen, dass der unterschiedliche Rückgabetyp überhaupt nicht notwendig wird.
TBackupJob hat ein weiteres Property aber das sollte doch keine Rolle spielen.
Die Klasse TJobList dient gleichzeitig hier als abstract Factory.
Aber anscheinend sind die erzeugten Objekte noch nicht vollständig initialisiert und nur aus diesem Grund brauchst du den konkreten Typ.

Eigentlich macht es auch keinen Sinn eine Ableitung von TJobList zu erstellen, denn es gibt keinen Grund,
weshalb nicht ganz unterschiedliche Job-Objekte in einer Liste geführt werden dürfen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:41 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