AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

virtual und override

Ein Thema von Hador · begonnen am 13. Sep 2005 · letzter Beitrag vom 14. Sep 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Hador
Hador

Registriert seit: 11. Dez 2004
Ort: Recke
682 Beiträge
 
Turbo Delphi für Win32
 
#1

virtual und override

  Alt 13. Sep 2005, 12:33
Das folgendes funktioniert ist mir klar:
Delphi-Quellcode:
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.
Aber wiso funktioniert auch folgendes? Bzw. worin liegt da der Unterschied?
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.
Lars Kiesow
http://www.larskiesow.de

Computer gehorchen deinen Befehlen, nicht deinen Absichten.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: virtual und override

  Alt 13. Sep 2005, 13:33
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.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

Re: virtual und override

  Alt 13. Sep 2005, 14:24
Zitat von Bernhard Geyer:
Im zweiten Fall [..] und in der Methodentabelle die Implementierung auf xy steht.
Im zweiten Fall gibt es gar keinen Eintrag in der VMT. Der Compiler ersetzt den Aufruf durch die direkte Adresse der Methode, die er im Gegensatz zu virtuellen Methoden kennt.
  Mit Zitat antworten Zitat
Benutzerbild von Hador
Hador

Registriert seit: 11. Dez 2004
Ort: Recke
682 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: virtual und override

  Alt 13. Sep 2005, 16:21
Erstmal danke für die Antworten.
Da tun sich dann aber bei mir gleich mal folgende Fragen auf:

1. Warum eine Variable vom Typ xy Definieren, wenn Der Variable der Typ yz zugewiesen wird.
Also warum
Delphi-Quellcode:
var x: xy
begin
  x := yz.create;
end;
und nicht
Delphi-Quellcode:
var x: yz
begin
  x := yz.create;
end;
2. Warum kann ich der Variable vom Typ xy ein Objekt vom Typ yz zuweisen.
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.
Lars Kiesow
http://www.larskiesow.de

Computer gehorchen deinen Befehlen, nicht deinen Absichten.
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#5

Re: virtual und override

  Alt 13. Sep 2005, 16:35
Zitat von Hador:
1. Warum eine Variable vom Typ xy Definieren, wenn Der Variable der Typ yz zugewiesen wird.
Stell dir vor du sammelst daten in Objekten. Die Daten haben alle eine ähnliche Struktur, unterscheiden sich aber doch in rgendetwas. Also schreibst du eine Vaterklasse und leitest davon deine Klassen ab. Jetzt kriegst du einen Datenstrom mit 100 Datensätzen und willst die irgendwo unterbringen. Also kannst du ein Array der Vaterklasse erzeugen und kannst in dieses Array lauter Objekte der Kindklasse stecken, obwohl das Array eigentlich vom Typ der Vaterklasse ist. Zur Laufzeit schaust du dann, von welcher Art der aktuelle datensatz ist und erzeugst entsprechend das richtige Objekt. Würdest du für jede Art von Datensatz ein eigenes Array des richtigen Typs vorhalten, kann es unübersichtlich werden.

Zitat von Hador:
2. Warum kann ich der Variable vom Typ xy ein Objekt vom Typ yz zuweisen.
Weil Klassen in einer Hierarchie nach oben zuweisungskompatibel sind. Du kannst also einer Variable einer Vaterklasse immer ein Objekt einer abgeleiteten Klasse übergeben, egal die wievieilte Ableitung es ist. Beispielsweise kann eine Variable vom Typ TControl alle Controls der VCL beinhalten, von Memo bis Button, weil alle VCL-Controls von TControl abgeleitet sind, obwohl bei einigen noch Klassen dazwischenliegen (z.B. TWinControl, TCustomMemo, etc).

Zitat von Hador:
Andersherum währe es ja noch zu verstenen, denn yz beinhaltet ja xy aber xy ist doch nur ein Teil von yz.
Eben deswegen geht es.
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.
  Mit Zitat antworten Zitat
Benutzerbild von Hador
Hador

Registriert seit: 11. Dez 2004
Ort: Recke
682 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: virtual und override

  Alt 13. Sep 2005, 16:54
Danke das habe ich gebraucht.

Jetzt sehe ich klarer.
Lars Kiesow
http://www.larskiesow.de

Computer gehorchen deinen Befehlen, nicht deinen Absichten.
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

Re: virtual und override

  Alt 13. Sep 2005, 17:20
Zitat von Hador:
Danke das habe ich gebraucht.
Jetzt sehe ich klarer.
Man sollte sich aber über die Auswirkungen vom Verdecken der Methoden bewust sein.
Da können sich leicht Fehler in ein Programm einschleichen, die man dann manchmal lange suchen muss

Zitat von Hador:
EDIT: Evt. verstehe ich das ja, wenn ihr mir mal 'n praktisches Beispiel vorwerft.
Unterschiede zwischen Überschreiben und Verdecken
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;
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

Re: virtual und override

  Alt 13. Sep 2005, 18:03
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ß.
Angehängte Dateien
Dateityp: zip beispiel_891.zip (1,6 KB, 5x aufgerufen)
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
Benutzerbild von Hador
Hador

Registriert seit: 11. Dez 2004
Ort: Recke
682 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: virtual und override

  Alt 13. Sep 2005, 19:12
Zitat von MaBuSE:
Man sollte sich aber über die Auswirkungen vom Verdecken der Methoden bewust sein.
Da können sich leicht Fehler in ein Programm einschleichen, die man dann manchmal lange suchen muss
Da is mir grad noch aufgefallen:

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 ?
Lars Kiesow
http://www.larskiesow.de

Computer gehorchen deinen Befehlen, nicht deinen Absichten.
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#10

Re: virtual und override

  Alt 13. Sep 2005, 19:26
Zitat von Hador:
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 ?
Beim Überschreiben von Methoden muss die Funktionssignatur gleich bleiben, aber du kannst die MEthode im Parent zusätzlich zu virtual noch mit overload deklarieren und dann in der abgeleiteten Klasse ebenfalls. Dann brauchst du aber eigenltich kein override mehr, weil es eben eine andere Methode ist, d.h. du wirst auch nicht über eine Variable des Vatertyps auf die überladenen Methoden der Kindklasse zugreifen können.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 20:11 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