Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   virtuelle Methode "nicht" überschreiben (https://www.delphipraxis.net/157849-virtuelle-methode-nicht-ueberschreiben.html)

himitsu 27. Jan 2011 09:21

Delphi-Version: XE

virtuelle Methode "nicht" überschreiben
 
Moin,

sag mal, gibt es in Delphi XE eigentlich die Möglichkeit, um zu sagen daß eine virtuelle Methode ab jetzt nicht mehr überschieben werden darf, also in den Nachkommen meiner Klasse?

[add]
Mir ist grad eingefallen, daß ich eventuell notfalls zur Laufzeit den in meiner Methode prüfen kann, ob dieses in der aktuellen VMT unverändert ist.

Neutral General 27. Jan 2011 09:22

AW: virtuelle Methode "nicht" überschreiben
 
Hallo,

Delphi-Quellcode:
type
  TA = class
    procedure ABC; virtual;
  end;

  TB = class(TA)
    procedure ABC; override; final;
  end;

  TC = class(TB)
    procedure ABC; override; // [DCC Fehler] Unit1.pas(33): E2352 Eine final-Methode darf nicht überschrieben werden
  end;

himitsu 27. Jan 2011 09:26

AW: virtuelle Methode "nicht" überschreiben
 
Danke :love:

Mir war auch so, als wenn ich da mal irgendwann irgendwas gesehn hatte.

SirThornberry 27. Jan 2011 18:24

AW: virtuelle Methode "nicht" überschreiben
 
Für was braucht man so etwas in der Praxis? Spontan würde mir kein Grund einfallen ein überschreiben einer virtuellen Methode verhindern zu wollen. :)

uligerhardt 27. Jan 2011 18:31

AW: virtuelle Methode "nicht" überschreiben
 
Zitat:

Zitat von SirThornberry (Beitrag 1077721)
Für was braucht man so etwas in der Praxis? Spontan würde mir kein Grund einfallen ein überschreiben einer virtuellen Methode verhindern zu wollen. :)

Das frage ich mich auch jedesmal, wenn ich über
Delphi-Quellcode:
final
oder
Delphi-Quellcode:
sealed
stolpere. Nachdem es aber alle "neuen" Programmiersprachen haben, war es offenbar überfällig, sowas zu efinden.:wink:

himitsu 27. Jan 2011 19:39

AW: virtuelle Methode "nicht" überschreiben
 
In meinem Fall war es einfach ein virtueller Constructor, wobei das auf alle virtuellen Methoden angewendet werden kann.

Es gibt eine Klasse, welche von einer anderen Klasse abgeleitet ist.
Nun ist hier ein neuer Contructor eingeführt, mit weiteren Parametern und es ist vorgesehen, daß weitere Nachfahren diesen neuen Contructor verwenden.
Intern wird der alte Contructor auf den neuen umgeleitet.

Nun ist es aber vorgesehen, daß diese Klasse öfters erweitert/abgeleitet wird und dabei soll einfach vermieden werden, daß die beiden Constructoren abwechseln überschrieben werden, was zur Folge hat, daß die Aufrufreihenfolge nicht mehr stimmt.

Delphi-Quellcode:
TMyClass0 = class()
  procedure MethodA; virtual;
end;

TMyClass1 = class(TMyClass0)
  procedure MethodA; overload;
  procedure MethodB; virtual;
end;

TMyClass2 = class(TMyClass1)
  procedure MethodB; overload;
end;

TMyClass3 = class(TMyClass2)
  procedure MethodA; overload;
  // eigentlich nicht "erlaubt", da es in MethodB gehören würde
end;

TMyClass4 = class(TMyClass3)
  procedure MethodB; overload;
end;



procedure TMyClass1.MethodA;
begin
  MethodB;
end;

procedure TMyClass1.MethodB;
begin
  inherited MethodA;
end;

// und sonst jeweils inherited auf den eigenen Vorfahren
TMyClass1 ist meine Klasse, auf TMyClass0 hab ich keinen Einfluß und das ab TMyClass2 unterliegt auch nicht unbedingt meiner Kontrolle.

Ruft man jetzt MethodB auf, dann würden die Methoden in dieser Reihenfolge ausgeführt:

TMyClass4.MethodB
TMyClass2.MethodB
TMyClass3.MethodA
TMyClass1.MethodA
TMyClass0.MethodA

Wie man sieht ist 2 und 3 vertauscht.
Darum einfach die alte Methode für's Überschreiben sperren, damit man das nicht ausversehn macht.


Grund ist einfach, daß die Komponente für billiges GUI-Geklicke mit Einstellung über den OI
und für die direkte Verwendung im Code, über Parameter im Contructor, verwendet werden kann.
Wobei im Code, mit dem dem alten Constructor und über Property auch möglich wäre. :stupid:


PS: sealed macht sich gut, wenn man eine öfentliche Klasse hat, von welcher aber nicht abgeleitet werden soll und die sich leider nicht privat deklarieren läßt, da man sie selber in mehreren Units benötigt.


PSS: Man hätte statt dem final die Methode einfach mit einer Nichtvirtuellen verdecken können, aber so ist es sauberer.

SirThornberry 28. Jan 2011 11:54

AW: virtuelle Methode "nicht" überschreiben
 
Zitat:

PSS: Man hätte statt dem final die Methode einfach mit einer Nichtvirtuellen verdecken können, aber so ist es sauberer.
Das auf jeden Fall. Zumal verdecken überhaupt nichts bringt wenn Vererbung im Spiel ist und man die Klasseninstanz über die Basisklasse ansteuert.

mjustin 29. Jan 2011 09:16

AW: virtuelle Methode "nicht" überschreiben
 
Zitat:

Zitat von SirThornberry (Beitrag 1077721)
Für was braucht man so etwas in der Praxis? Spontan würde mir kein Grund einfallen ein überschreiben einer virtuellen Methode verhindern zu wollen. :)

Joshua Bloch (Author von "Effective Java") empfiehlt, final mmer dann zu verwenden, wenn eine Klasse oder Methode nicht für Erweiterungen entworfen wurde. Einige Beiträge auf Stack Overflow nennen API Design als Haupteinsatzgebiet für final deklarierte Klassen und Methoden. Man kann das auf Delphi auch anwenden - es schadet nicht, den anderen Entwicklern explizit zu zeigen, welche der Methoden man für Erweiterbarkeit entworfen hat und welche nicht.


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