随笔 - 2047  文章 - 71 评论 - 10629 trackbacks - 253

提示1: 点击 标题 可进入首页;   提示2: 从搜索引擎中搜索 万一 可迅速找到这里.
昵称:万一
园龄:4年3个月
荣誉:推荐博客
粉丝:349
关注:34

随笔分类(2499)

随笔档案(2051)

积分与排名

  • 积分 - 4148339
  • 排名 - 4

最新评论


在今后的 Delphi 中, 以接口、结构为主的设计应该会越来越多, 因为这样太方便了.

System.RegularExpressions 就是以结构为主体设计的非常好的示范; 但更多东西使用接口会更合适.

有见过他人早就使用接口写程序, 从手头的这个程序开始我才开始使用.

现在基本总结出四种框架模式: 1、直接实现; 2、间接实现(或叫继承实现); 3、覆盖实现; 4、委托实现.

一、直接实现:

下例中虽有 TMy1、TMy2, 但在具体应用中使用的应是 IMy1、IMy2, 这就是我所谓的以接口为主导.
TMy1、TMy2 直接实现了所属接口的所有方法, 这是我所谓的直接实现.
这样可能会有代码重复, 但如果程序很小, 还是挺实用的.

unit Unit1;

interface

uses
  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;

interface

uses
  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;

interface

uses
  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 和其它系统都不行, 还学它干嘛?

posted on 2012-01-03 18:01 万一 阅读(822) 评论(1) 编辑 收藏

FeedBack:
#1楼 2012-01-05 16:32 飘雪love      
哈哈,万一老师我最近也再看接口相关的资料。
就是不知道有哪些书籍为好,可否提供呢?
以后多看看万一老师如何学习接口的。

 回复 引用 查看