一、直接实现: 下例中虽有 TMy1、TMy2, 但在具体应用中使用的应是 IMy1、IMy2, 这就是我所谓的以接口为主导. TMy1、TMy2 直接实现了所属接口的所有方法, 这是我所谓的直接实现. 这样可能会有代码重复, 但如果程序很小, 还是挺实用的.
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; IA = Interface procedure Method_A; end; IB = Interface(IA) procedure Method_B; end; IMy1 = Interface(IB) procedure Method_My1; end; IMy2 = Interface(IB) procedure Method_My2; end; TMy1 = class(TInterfacedObject, IMy1) procedure Method_A; procedure Method_B; procedure Method_My1; end; TMy2 = class(TInterfacedObject, IMy2) procedure Method_A; procedure Method_B; procedure Method_My2; end;var Form1: TForm1;implementation{$R *.dfm}{ TMy1 }procedure TMy1.Method_A;begin ShowMessage('A');end;procedure TMy1.Method_B;begin ShowMessage('B');end;procedure TMy1.Method_My1;begin ShowMessage('My1');end;{ TMy2 }procedure TMy2.Method_A;begin ShowMessage('A');end;procedure TMy2.Method_B;begin ShowMessage('B');end;procedure TMy2.Method_My2;begin ShowMessage('My2');end;{测试}procedure TForm1.FormCreate(Sender: TObject);var v1: IMy1; v2: IMy2;begin v1 := TMy1.Create; v1.Method_A; v1.Method_B; v1.Method_My1; v2 := TMy2.Create; v2.Method_A; v2.Method_B; v2.Method_My2;end;end.
二、间接实现: 下面例子通过一个间接的 TB 类, 避免了 TMy1、TMy2 中可能会重复的代码.
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; IA = Interface procedure Method_A; end; IB = Interface(IA) procedure Method_B; end; TB = class(TInterfacedObject, IB) procedure Method_A; procedure Method_B; end; IMy1 = Interface(IB) procedure Method_My1; end; IMy2 = Interface(IB) procedure Method_My2; end; TMy1 = class(TB, IMy1) procedure Method_My1; end; TMy2 = class(TB, IMy2) procedure Method_My2; end;var Form1: TForm1;implementation{$R *.dfm}{ TB }procedure TB.Method_A;begin ShowMessage('A');end;procedure TB.Method_B;begin ShowMessage('B');end;{ TMy1 }procedure TMy1.Method_My1;begin ShowMessage('My1');end;{ TMy2 }procedure TMy2.Method_My2;begin ShowMessage('My2');end;{测试}procedure TForm1.FormCreate(Sender: TObject);var v1: IMy1; v2: IMy2;begin v1 := TMy1.Create; v1.Method_A; v1.Method_B; v1.Method_My1; v2 := TMy2.Create; v2.Method_A; v2.Method_B; v2.Method_My2;end;end.
三、覆盖实现: 从 TB 继承的过程中当然也可以通过覆盖虚函数而实现多态, 下面的 TMy2 就这么做了.
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; IA = Interface procedure Method_A; end; IB = Interface(IA) procedure Method_B; end; TB = class(TInterfacedObject, IB) procedure Method_A; virtual; procedure Method_B; virtual; end; IMy1 = Interface(IB) procedure Method_My1; end; IMy2 = Interface(IB) procedure Method_My2; end; TMy1 = class(TB, IMy1) procedure Method_My1; end; TMy2 = class(TB, IMy2) procedure Method_A; override; procedure Method_B; override; procedure Method_My2; end;var Form1: TForm1;implementation{$R *.dfm}{ TB }procedure TB.Method_A;begin ShowMessage('A');end;procedure TB.Method_B;begin ShowMessage('B');end;{ TMy1 }procedure TMy1.Method_My1;begin ShowMessage('My1');end;{ TMy2 }procedure TMy2.Method_A;begin ShowMessage('A_My2');end;procedure TMy2.Method_B;begin ShowMessage('B_My2');end;procedure TMy2.Method_My2;begin ShowMessage('My2');end;{测试}procedure TForm1.FormCreate(Sender: TObject);var v1: IMy1; v2: IMy2;begin v1 := TMy1.Create; v1.Method_A; v1.Method_B; v1.Method_My1; v2 := TMy2.Create; v2.Method_A; v2.Method_B; v2.Method_My2;end;end.
四、委托实现: 接口中的方法是肯定要实现的, 但也可以通过 implements 关键字借用(或叫委托)其它的实现; 但, 官方文档说这只适用于 Win32. 就是说这种方法在 Win64 和其它系统都不行, 还学它干嘛?