![]() |
virtual und override
Das folgendes funktioniert ist mir klar:
Delphi-Quellcode:
Aber wiso funktioniert auch folgendes? Bzw. worin liegt da der Unterschied?
unit Unit3;
interface type xy = class x, y: integer; function get_str: string; virtual; end; type yz = class(xy) function get_str: string; override; end; implementation function xy.get_str: string; begin result := #32; end; function yz.get_str: string; begin result := #33; end; end. Denn hier wird die Funktion get_str ja auch überschrieben, jedoch ohne dass sie vorher per virtual als überschreibbar deklariert wurde.
Delphi-Quellcode:
unit Unit2;
interface type xy = class x, y: integer; function get_str: string; end; type yz = class(xy) function get_str: string; end; implementation function xy.get_str: string; begin result := #32; end; function yz.get_str: string; begin result := #33; end; end. |
Re: virtual und override
Der unterschied ist dann gegeben wenn Du ein Objekt des Typs yz in einer Variable des Typs xy hast.
Im ersten Fall mit virtual/override wird die Methode von yz aufgerufen da in der Methodentabelle die Einsprungsadresse von der Implementierung in yz steht. Im zweiten Fall wird die Methode von xy aufgerufen, da die Variable von diesem Typ ist und in der Methodentabelle die Implementierung auf xy steht. |
Re: virtual und override
Zitat:
|
Re: virtual und override
Erstmal danke für die Antworten. :thumb:
Da tun sich dann aber bei mir gleich mal folgende Fragen auf: :gruebel: 1. Warum eine Variable vom Typ xy Definieren, wenn Der Variable der Typ yz zugewiesen wird. Also warum
Delphi-Quellcode:
und nicht
var x: xy
begin x := yz.create; end;
Delphi-Quellcode:
2. Warum kann ich der Variable vom Typ xy ein Objekt vom Typ yz zuweisen.
var x: yz
begin x := yz.create; end; Andersherum währe es ja noch zu verstenen, denn yz beinhaltet ja xy aber xy ist doch nur ein Teil von yz. EDIT: Evt. verstehe ich das ja, wenn ihr mir mal 'n praktisches Beispiel vorwerft. :wink: |
Re: virtual und override
Zitat:
Zitat:
Zitat:
Weil xy nur ein Teil von yz ist, kansnt du ein Objekt von yz einer Variable vom Typ xy zuweisen, weil der Compiler sicher sein kann, daß alles, was über die Variable zugänglich ist (an Feldern und Methoden) auch in dem Objekt von yz existieren. Andersrum hätte man die Klasse yz gegenüber xy erweitern können. Weise ich jetzt einer Variable vom Typ yz ein Objekt vom Typ xy zu, ist nicht der gesamte Speicher, den ich durch die Variable zugreifen kann, allokiert, weil ja die Klasse yz größer ist als xy. |
Re: virtual und override
Danke das habe ich gebraucht. :thumb:
Jetzt sehe ich klarer. |
Re: virtual und override
Zitat:
Da können sich leicht Fehler in ein Programm einschleichen, die man dann manchmal lange suchen muss ;-) Zitat:
Wenn in einer Methodendeklaration dieselben Bezeichner- und Parameterangaben wie bei einer geerbten Methode ohne die Anweisung override angegeben werden, wird die geerbte Methode durch die neue Deklaration verdeckt. Beide Methoden sind jedoch in der abgeleiteten Klasse vorhanden, in der die Methode statisch gebunden wird. Bei T2 werden Compilerwarnungen ausgegeben, das die Methoden verdeckt sind. Mithilfe der Anweisung reintroduce kann verhindert werden, dass der Compiler Warnungen ausgibt, wenn eine zuvor deklarierte virtuelle Methode verdeckt wird, aber das Verhalten ist trotzdem das Selbe. Unterschiede zwischen virtuellen und dynamischen Methoden Virtuelle und dynamische Methoden sind von der Semantik her identisch. Sie unterscheiden sich nur bei der Implementierung der Aufrufverteilung zur Laufzeit. Virtuelle Methoden werden auf Geschwindigkeit, dynamische Methoden auf Code-Größe optimiert. Im Allgemeinen kann mit virtuellen Methoden polymorphes Verhalten am effizientesten implementiert werden. Dynamische Methoden sind hilfreich, wenn in einer Basisklasse eine große Anzahl überschreibbarer Methoden deklariert ist, die von vielen abgeleiteten Klassen geerbt, aber nur selten überschrieben werden.
Delphi-Quellcode:
type
T1 = class(TObject) procedure A; virtual; procedure B; dynamic; procedure C; end; T2 = class(T1) procedure A; // Methoden sind neu deklariert, aber nicht überschrieben procedure B; procedure C; end; T3 = class(T1) procedure A; override; // Methoden sind überschrieben procedure B; override; // procedure C; override; // Fehlermeldung, es können keine statischen Methoden überschrieben werden end; ... var Obj1: T1; Obj2: T2; Obj3: T3; begin // das ist klar Obj1 := T1.Create; Obj1.A; // T1.A wird aufgerufen Obj1.B; // T1.B wird aufgerufen Obj1.C; // T1.C wird aufgerufen Obj1.Free; // das ist klar Obj2 := T2.Create; Obj2.A; // T2.A wird aufgerufen Obj2.B; // T2.B wird aufgerufen Obj2.C; // T2.C wird aufgerufen Obj2.Free; // das ist klar Obj3 := T3.Create; Obj3.A; // T3.A wird aufgerufen Obj3.B; // T3.B wird aufgerufen Obj3.C; // T1.C wird aufgerufen, da nicht überschrieben Obj3.Free; // Achtung: Das ist oft nicht gewünscht Obj1 := T2.Create; Obj1.A; // T1.A wird aufgerufen Obj1.B; // T1.B wird aufgerufen Obj1.C; // T1.C wird aufgerufen T2(Obj1).A; // T2.A wird aufgerufen T2(Obj1).B; // T2.B wird aufgerufen T2(Obj1).C; // T2.C wird aufgerufen Obj1.Free; // Achtung: So sollte es (meistens) sein Obj1 := T3.Create; Obj1.A; // T3.A wird aufgerufen Obj1.B; // T3.B wird aufgerufen Obj1.C; // T1.C wird aufgerufen, da nicht überschrieben Obj1.Free; end; |
Re: virtual und override
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe obiges Beispiel mal in mein Delphi getippt und etwas erweitert :-)
Ich hoffe nun ist der Unterschied zwischen verdecken und überschreiben klar. Viel Spaß. |
Re: virtual und override
Zitat:
Sobald man der neuen Prozedur/Funktion jedoch mehr Parameter zuweist, funktioniert override nicht mehr, bzw. Delphi lässt das nicht zu. Das verdecken funktioniert jedoch. Gibt es dort auch eine Möglichkeit die alte Methode zu überschreiben, oder macht Delphi da dann sozusagen eine Überladene Mthode raus, und sucht sich aufgrund der Parameteranzahl bzw. des Parametertyps die passende Methode raus ? |
Re: virtual und override
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 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 by Thomas Breitkreuz