![]() |
Delphi-Version: 5
Inherited "überspringen"?
Man betrachte folgende Struktur:
Delphi-Quellcode:
Man nehme weiterhin an, dass ich als Programmierer nur den Code ab Unterklasse2 modifizieren kann (weil zb. der Rest in irgendwelchen Standardbibliotheken ist).
Oberklasse = class(TObject)
protected procedure Proc; virtual; Unterklasse1 = class(Oberklasse) protected procedure Proc; override; Unterklasse2 = class(Unterklasse1) protected procedure Proc; override; Zudem sei Unterklasse1.Proc so implementiert, dass es in Randfällen im Anwendungskontext, in dem auch Unterklasse2 steht (also das Programm, von dem Unterklasse2 ein Teil ist), zu Fehlern kommt. Dies ist überhaupt erst der Grund, warum ich in Unterklasse2 Proc nocheinmal implementiere. Nun ist es so, dass in Unterklasse1.Proc inherited, also Oberklasse.Proc aufgerufen wird. Diesen Aufruf würde ich auch gerne behalten. Wenn ich aber Unterklasse2.Proc folgendermaßen implementiere:
Delphi-Quellcode:
würde der (fehlerhafte) Code von Unterklasse1.Proc wieder aufgerufen werden.
procedure Unterklasse2.Proc;
begin [...] inherited; end; Lange Rede, kurze Frage: ist es möglich beim inherited Stufen in der Hierarchie zu "überspringen"? Oder eine spezifische Implementierung von Proc aufzurufen? |
AW: Inherited "überspringen"?
Naja....du könntest z.B. folgendes machen:
Delphi-Quellcode:
procedure Unterklasse2.Proc;
begin [...] Oberklasse.proc; end; |
AW: Inherited "überspringen"?
Hm... Tatsache. Tja, manchmal geht's es ganz einfach :-D
Danke! |
AW: Inherited "überspringen"?
Zitat:
Zitat:
|
AW: Inherited "überspringen"?
Hallo,
ist es möglich beim inherited Stufen in der Hierarchie zu "überspringen"? Oder eine spezifische Implementierung von Proc aufzurufen? Kurze Antwort: nein Lange Antwort: es kommt drauf an In deiner eigenen Klasse kannst du das inherited ja weglassen, musst dann aber wissen, was in den darüberliegenden Klasse gemacht wird, dann könntest du aber gleich reintroduce nehmen. Oder du rufst das inherited auf und korrigierst dann die falschen Daten, falls das geht. |
AW: Inherited "überspringen"?
Eventuell so?
Delphi-Quellcode:
procedure Unterklasse2.Proc;
begin [...] Oberklasse(Self).proc; end; |
AW: Inherited "überspringen"?
Zitat:
|
AW: Inherited "überspringen"?
Hallo,
Delphi-Quellcode:
Wenn aber Oberklasse.Proc dann das fehlerhafte inherited aufruft,
Oberklasse(Self).proc;
geht wieder alles schief ... |
AW: Inherited "überspringen"?
Zitat:
|
AW: Inherited "überspringen"?
Zitat:
Die einzige Möglichkeit, die mir dazu einfällt ist schon arg bösartig:
Delphi-Quellcode:
procedure Unterklasse2.Proc;
begin asm mov eax,self call Oberklasse.Proc end; // inherited; Writeln('Unterklasse2'); end; |
AW: Inherited "überspringen"?
Ich würde das lieber so sauber wie eben möglich ohne Assembler lösen:
Delphi-Quellcode:
uses
System.Rtti, System.TypInfo; procedure Unterklasse2.Proc; begin System.Rtti.Invoke(@Oberklasse.Proc, TArray<TValue>.Create(TValue.From<Unterklasse2>(Self)), ccReg, nil); end; |
AW: Inherited "überspringen"?
Außer den Möglichkeiten von Uwe und Jaenike hab ich keine weiteren gefunden.
Da du aber Unterklasse2 eh nur wegen eines Fehlers in Unterklasse1 baust, warum leitest du das ganze nicht direkt von Oberklasse ab ? Dann kann Unterklasse1 über die Klinge springen. |
AW: Inherited "überspringen"?
Zitat:
Mein spezifisches Problem war anders lösbar, weil die Oberklasse.Proc nen Einzeiler mit nem Zugriff auf eine Published Property war (check auf Ereignisbehandlung) und ich das deshalb schmerzfrei nachbauen konnte. Die Diskussion interessiert mich dennoch. Ähnliche Fälle werden in Zukunft wahrscheinlich nochmal auftreten. Zitat:
|
AW: Inherited "überspringen"?
Noch eine Dritte Variante ohne Assembly oder RTTI:
Delphi-Quellcode:
{ TA }
procedure TA.X(I: Integer); begin ShowMessage('1: ' + I.ToString); end; { TB } procedure TB.X(I: Integer); begin inherited; ShowMessage('2: ' + I.ToString); end; { TC } procedure TC.X(I: Integer); type TProc = procedure(Sender: TA; I: Integer); begin //inherited; TProc(@TA.X)(Self, I); ShowMessage('3: ' + I.ToString); end; |
AW: Inherited "überspringen"?
Nein. Solltest du meiden.
Es gibt in C++ diese Art des Aufrufs, mit dem wird aber im Falle von Multiple Inheritance zwischen den Base Classes unterschieden in erster Linie. Gute Frage wäre ob du nicht einfach ein Objekt der entfernten Basisklasse erzeugst und das Ergebnis verwendest. Ob das Sinn macht sei dahingestellt. Ich würde nicht ausschließen, ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz