AGB  ·  Datenschutz  ·  Impressum  







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

Halb-virtuelle Methoden

Offene Frage von "Sir Rufo"
Ein Thema von Der schöne Günther · begonnen am 30. Dez 2014 · letzter Beitrag vom 30. Dez 2014
Antwort Antwort
Seite 2 von 2     12   
Dejan Vu
(Gast)

n/a Beiträge
 
#11

AW: Halb-virtuelle Methoden

  Alt 30. Dez 2014, 21:35
Ich muss mich korrigieren, das ist nicht 'typisch halbausgegorener Delphi-Mist', wie ich schrieb, sondern vollkommen korrekt, das das so ist. Verwirrend, aber korrekt.

TMyClass implementiert das Interface und die Methode interfaceproc und TMyChild schert sich einen feuchten Kericht darum und ersetzt/überschreibt (wortwörtlich) die Methode durch eine eigene Implementierung.

Dreckig, sollte verboten sein, aber legal.

PS: C# hätte in 'TMyChild' gerne das 'new' Schlüsselwort, damit man sieht, das 'interfaceproc' *neu* implementiert wurde, aber notwendig ist auch dort nicht...

Geändert von Dejan Vu (30. Dez 2014 um 21:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: Halb-virtuelle Methoden

  Alt 30. Dez 2014, 23:23
Ich habe das Beispiel mal erweitert, damit man die ganzen Spielarten sieht
Delphi-Quellcode:
program dp_183307;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  IMyInterface = interface
    procedure interfaceProc1( );
    procedure interfaceProc2( );
  end;

  TMyBase = class( TInterfacedObject, IMyInterface )
    procedure interfaceProc1( ); // virtual;
    procedure interfaceProc2( ); virtual;
  end;

  TMyChild = class( TMyBase, IMyInterface )
    procedure interfaceProc1( ); // override;
    procedure interfaceProc2( ); override;
  end;

procedure TMyBase.interfaceProc1( );
begin
  WriteLn( 'TMyBase.interfaceProc1' );
end;

procedure TMyBase.interfaceProc2;
begin
  WriteLn( 'TMyBase.interfaceProc2' );
end;

procedure TMyChild.interfaceProc1( );
begin
  inherited;
  WriteLn( 'TMyChild.interfaceProc1' );
end;

procedure TMyChild.interfaceProc2;
begin
  inherited;
  WriteLn( 'TMyChild.interfaceProc2' );
end;

procedure Test1;
var
  LIntf: IMyInterface;
  LInst: TMyBase;
begin
  WriteLn( 'LInst[TMyBase] := TMyBase.Create' );
  LInst := TMyBase.Create;
  LInst.interfaceProc1;
  LInst.interfaceProc2;
  WriteLn( 'LIntf <- LInst' );
  LIntf := LInst;
  LIntf.interfaceProc1;
  LIntf.interfaceProc2;
end;

procedure Test2;
var
  LIntf: IMyInterface;
  LInst: TMyBase;
begin
  WriteLn( 'LInst[TMyBase] := TMyChild.Create' );
  LInst := TMyChild.Create;
  LInst.interfaceProc1;
  LInst.interfaceProc2;
  WriteLn( 'LIntf <- LInst' );
  LIntf := LInst;
  LIntf.interfaceProc1;
  LIntf.interfaceProc2;
end;

procedure Test3;
var
  LIntf: IMyInterface;
  LInst: TMyChild;
begin
  WriteLn( 'LInst[TMyChild] := TMyChild.Create' );
  LInst := TMyChild.Create;
  LInst.interfaceProc1;
  LInst.interfaceProc2;
  WriteLn( 'LIntf <- LInst' );
  LIntf := LInst;
  LIntf.interfaceProc1;
  LIntf.interfaceProc2;
end;

begin
  try
    WriteLn('Test1');
    Test1;
    WriteLn;
    WriteLn('Test2');
    Test2;
    WriteLn;
    WriteLn('Test3');
    Test3;
  except
    on E: Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
Damit erhalten wir folgende Ausgabe
Code:
Test1
LInst[TMyBase] := TMyBase.Create
TMyBase.interfaceProc1
TMyBase.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyBase.interfaceProc2

Test2
LInst[TMyBase] := TMyChild.Create
TMyBase.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2

Test3
LInst[TMyChild] := TMyChild.Create
TMyBase.interfaceProc1
TMyChild.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyChild.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
Jetzt kommt das Schmankerl ... und nehmen bei TMyChild das Interface weg TMyChild = class( TMyBase{, IMyInterface} ) .

Jetzt erhalten wir diese Ausgabe
Code:
Test1
LInst[TMyBase] := TMyBase.Create
TMyBase.interfaceProc1
TMyBase.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyBase.interfaceProc2

Test2
LInst[TMyBase] := TMyChild.Create
TMyBase.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2

Test3
LInst[TMyChild] := TMyChild.Create
TMyBase.interfaceProc1
TMyChild.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
LIntf <- LInst
TMyBase.interfaceProc1
TMyBase.interfaceProc2
TMyChild.interfaceProc2
Lustig, gell?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 14:36 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