Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Halb-virtuelle Methoden (https://www.delphipraxis.net/183307-halb-virtuelle-methoden.html)

Dejan Vu 30. Dez 2014 20:35

AW: Halb-virtuelle Methoden
 
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
Delphi-Quellcode:
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...

Sir Rufo 30. Dez 2014 22:23

AW: Halb-virtuelle Methoden
 
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
Delphi-Quellcode:
TMyChild
das Interface weg
Delphi-Quellcode:
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? ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 Uhr.
Seite 2 von 2     12   

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