AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen FreePascal Polymorphie bei Methodenrückgabewerten
Thema durchsuchen
Ansicht
Themen-Optionen

Polymorphie bei Methodenrückgabewerten

Ein Thema von Desmulator · begonnen am 29. Mär 2009 · letzter Beitrag vom 29. Mär 2009
Antwort Antwort
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#1

Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 00:14
Guten Morgen alle zusammen ,

ich arbeite momentan sehr viel mit Objekten und COM Interfaces. Da ich mir als Ziel gesetzt habe, wirlich sauberes OOP zumachen gibt es einige Probleme. Der Compiler macht nicht mit, genauer er erkennt die Polymorphie nicht. Folgenes Beispiel:

Objekt A besitzt die virtuelle abstrakte Methode XYZ, die das Interface C zurück gibt.
Objekt B, abgeleitet von Objekt A, überschreib die Methode XYZ, gibt allerdings Interface D, welches von Interface C abgeleitet ist zurück.
In meinen Augen ist das keine Verletzung der Regeln, da Interface D auch ein vollwertiges Interface C ist. Somit gibt die Funktion XYZ immer ein Interface C zurück, allerdings manchmal mehr als nur C.

Trozdem beschwert sich der Compiler: "There is no method in an ancestor to override". Ich habe das Problem jetzt mit reintroduce "gelöst", bzw. rein gewaschen, wirlich sauber ist das ja nicht, eine Methode einer zu streichen und was anderes hinschreiben, das ähnelt eher dem Overload als einer abstrakten Vererbung.
Fehlende "virtual"- oder "abstract"-Statements habe ich mehrmals ausgeschlossen.

Gibt es da wirklich keine Möglichkeit? Mit ordinalen Typen geht es ja auch, warum also nicht mit Interfaces und Classes, die im Prizip auch nur ordinal sind ( Pointer afaik ).

Für die, die den Beweis brauchen:

Delphi-Quellcode:
type
  TSubKlasse = class(TObject);
  TTopKlasse = class(TSubKlasse);

  TElternKlasse = class(TObject)
  public
    function Test : TSubKlasse; virtual; abstract;
  end;

  TKind1Klasse = class(TElternKlasse)
  public
    // TTopKlasse ist ein TSubKlasse, also gültig.
    function Test : TTopKlasse; override;
  end;

  TKind2Klasse = class(TElternKlasse)
  public
    // So gehts auch, mit brachialer Überschreibgewalt.
    function Test : TTopKlasse; reintroduce;
  end;

  TKind3Klasse = class(TElternKlasse)
  public
    // Allerdings auch so, was nicht OOP ist.
    function Test(Param1 : Integer) : TTopKlasse; reintroduce;
  end;
Naja hoffentlich gibts eine schöne Lösung, denn Code muss nicht nur funktionieren, Code muss gut aussehen, Code muss eine Persönlichkeit haben, Code muss Leben & Atmen... ^^

Gute Nacht! xD
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 00:54
Wenn TTopKlasse wirklich kein direkter Nachfahre von TObject ist, dann ist das (sowieso) nicht Polymorphie, sondern Varianz Und soweit ich das erkenne, unterstützt Delphi das nicht. Du musst immer mit exakter Signatur überschreiben.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.352 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 01:01
Wenn die Methode anders deklariert ist als in der Elternklasse, dann kannst du die der Elternklasse damit nicht überschreiben. Überschreiben bedeutet wirklich eine gleiche Deklaration. Denn das Ziel ist ja, über eine Variable vom Typ der Elternklasse mit einem Objekt vom Typ der abgeleiteten Klasse direkt die Methode aufrufen zu können.

Das geht aber nicht, wenn diese anders deklariert ist. Das ist nicht der Sinn des Überschreibens und damit nicht möglich. Mehrere gleichlautende Methoden werden überladen oder müssen neu eingeführt werden, anders geht es nicht.

Wenn du genauer sagen würdest worum es geht, dann könnte vielleicht jemand eine andere saubere OOP Lösung vorschlagen.

Dein Quelltextbeispiel ist etwas anders gelagert, oder? Oder geht es dir auch mit den Interfaces um verschieden deklarierte Methoden?
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von stoxx
stoxx

Registriert seit: 13. Aug 2003
1.111 Beiträge
 
#4

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 04:50
Zitat:
Methode einer zu streichen und was anderes hinschreiben, das ähnelt eher dem Overload als einer abstrakten Vererbung
ja korrekt, denn ich sehe keine Notwendigkeit für Polymorphie in Deinem Code ..
Deine Rückgabewerte sind unterschiedlich, also warum so eine Aufregung?
Zielorientierte Frage an Dich, was willst Du denn genau nun umsetzen?
Der Sinn von virtual und override ist Dir schon klar, oder?
Dein Beispiel hat mit Polymorphie leider überhaupt nix zu tun.
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#5

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 09:33
@stoxx & jaenicke: In der Theorie ist das kein Problem, Dax hat es ja schon angesprochen: Rückgabetypen sind kovariant. In Java oder C++ würde Desmulators Code funktionieren. (Ich gehe mal wie Dax davon aus, dass es eigentlich
TTopKlasse = class(TSubKlasse); // Merkwürdige Bezeichner ;) heißen sollte)

@Desmulator: Das einfachste wird es sein, in den abgeleiteten Klassen eine TestEx-Methode einzuführen, die dann das abgeleitete Interface zurückgibt. Im überschriebenen Test kannst du dann einfach TestEx zurückgeben. Gut, wenn du diese Klasse dann nochmal ableiten willst, wird es langsam hässlich .
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#6

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 10:09
Danke für die Antworten,

es handelt sich wirklich um einen "Tippfehler", wie Khabarakh vermuted hatte. Ich habe es korrigiert. Die Bezeichner sollen ja nur den Sachverhalt darstellen.

Ich habe nochmal genau nachgeschaut, das Problem stellt sich nur bei vererbten Interfaces.
Beispiel :
Delphi-Quellcode:
program Project1;

{ $mode objfpc}{ $H+}

type
  ISubKlasse = interface(IInterface) end;
  ITopKlasse = interface(ISubKlasse) end;
  TSubKlasse = class(TInterfacedObject, ISubKlasse);
  TTopKlasse = class(TSubKlasse, ITopKlasse);


  TElternKlasse = class(TObject)
  public
    function Test : TSubKlasse; virtual;
    function Test2 : ISubKlasse; virtual;
  end;

  TKind1Klasse = class(TElternKlasse)
  public
    // TTopKlasse ist ein TSubKlasse, also gültig.
    function Test : TTopKlasse; override;
    function Test2 : ITopKlasse; override;
    // Diese Zeile wir bestraft mit der Meldung:
    // project1.lpr(22,14) Error: There is no method in an ancestor class to be overridden: "TKind1Klasse.Test2:ITopKlasse"
  end;

  TKind2Klasse = class(TElternKlasse)
  public
    // So gehts auch, mit brachialer Überschreibgewalt.
    function Test : TTopKlasse; reintroduce;
    function Test2 : ITopKlasse; reintroduce;
  end;

function TElternKlasse.Test : TSubKlasse;
begin
  Result := TSubKlasse.Create();
end;

function TKind1Klasse.Test : TTopKlasse;
begin
  Result := TTopKlasse.Create();
end;

function TKind2Klasse.Test : TTopKlasse;
begin
  Result := TTopKlasse.Create();
end;

function TElternKlasse.Test2 : ISubKlasse;
begin
  Result := ISubKlasse(Test);
end;

function TKind1Klasse.Test2 : ITopKlasse;
begin
  Result := ITopKlasse(Test);
end;

function TKind2Klasse.Test2 : ITopKlasse;
begin
  Result := ITopKlasse(Test);
end;

begin
end.
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.352 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 16:27
Mit Klassen klappt das so? Das hätte ich nicht gedacht, das muss ich direkt einmal ausprobieren. Ich dachte die Deklaration müsste exakt übereinstimmen.

Dass es einen Unterschied zwischen Klassen und Interfaces gibt, wäre allerdings an der Stelle seltsam. Ich probiere es einmal aus.

// EDIT:
Mit welcher Delphiversion klappt das denn bei dir? ich bekomme selbst mit der neuesten Version 2009 einen Fehler in beiden Zeilen:
Zitat:
[DCC Fehler] Project220.dpr(21): E2037 Deklaration von 'Test' unterscheidet sich von vorheriger Deklaration
[DCC Fehler] Project220.dpr(22): E2037 Deklaration von 'Test2' unterscheidet sich von vorheriger Deklaration
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#8

Re: Polymorphie bei Methodenrückgabewerten

  Alt 29. Mär 2009, 16:59
Ich nutze Lazarus mit FreePascal 2.0.2 im objfpc-mode, aber auch im delphi-mode funktioniert es. Kontrollier mal deine CompilerEinstellungen, ich meine zu wissen, aus meinen alten delphi zeiten, dass man da irgendwas einstellen kann. In der nähe wo es auch die StackOverflow Prüfung zum ein und ausschalten gibt uws.

Nun mit "normalen" Typen sollte es aber gehen.

Delphi-Quellcode:
  
  TInteger1 = Integer;
  TInteger2 = TInteger1;

  TElternKlasse = class(TObject)
  public
...
    function Test3 : TInteger1; virtual; abstract; // Absract oder nicht, spielt keine Rolle.
  end;

  TKind1Klasse = class(TElternKlasse)
  public
...
    function Test3 : TInteger2; override;
  end;
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:58 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