Delphi 接口编程之:接口委托

本文假设你懂得 Delphi 的接口编程(关键词:Interface)

假设我们定义了一个接口 IA,它有一个或几个方法。这里假设这个接口定义只有一个方法。

然后,我们有两个不同的类,都实现了这个 IA 接口。但对其方法的实现,有点不一样。假设这两个类分别是 X 和 Y。也就是说,调用 X 的接口方法,和调用 Y 的同样接口的同名方法,得到的结果不同。这类似于对象继承的多态所要达到的目标。

然后,我们有一个类 Z,它也实现了接口 IA。但是,它不用真正地实现一次 IA 的方法所需要的代码,它仅仅是委托给 X 或者 Y 就可以了。为什么要这样做?理由大概有几点:

1. 这个 Z 除了需要实现接口 IA 所提供的方法,还需要提供其它一些方法。

2. 这个 Z 作为一些对象或者接口的封装,对外隐藏代码的复杂性。


如果这个 Z 是采用委托的方式,将自己实现的接口,委托给 X 或 Y,则在运行期,是可以动态切换到。这样一来,就可以根据不同的情况,调用相同的接口方法,获得不同的运行结果,实现不同的功能。这样的代码,可以避免一堆的 if.. else,也更方便将来增加新的功能,而无需去更改 Z 的代码。


详细演示代码,已经上传到 CNDEV 里面。这里是下载地址。


以下是部分代码:

unit UMyIntf;
{------------------------------------------------------------------------
  接口委托及运行期动态更换的演示代码。

  pcplayer 2017-5-31
------------------------------------------------------------------------}
interface

uses System.SysUtils, System.Variants, System.Classes;

type
  IMyIntf = interface
    ['{9FC4FAA4-04F1-4799-9C30-BB444214E292}']
    function Hello(const S: string): string;
  end;

  IHelloIndex = interface
    ['{C994DC32-D4CB-44F3-8A4D-7E3A6798A7DC}']
    procedure SetMyIndex(const Value: Integer);
    property MyIndex: Integer write SetMyIndex;
  end;


  TEngHello = class(TComponent, IMyIntf)
  public
    function Hello(const S: string): string;
  end;

  TChinaHello = class(TComponent, IMyIntf)
  public
    function Hello(const S: string): string;
  end;

  TMyHello = class(TComponent, IMyIntf, IHelloIndex)
  private
    FMyIntf: IMyIntf;
    FMyIndex: Integer;

    FEngHello: TEngHello;
    FChinaHello: TChinaHello;
    procedure SetMyIndex(const Value: Integer);
  public
    constructor Create(AOwner: TComponent); override;

    property MyIntf: IMyIntf read FMyIntf implements IMyIntf;
    property MyIndex: Integer write SetMyIndex;
  end;

const
  IID_IHelloIndex: TGUID = '{C994DC32-D4CB-44F3-8A4D-7E3A6798A7DC}';
  IID_IMyIntf: TGUID = '{9FC4FAA4-04F1-4799-9C30-BB444214E292}';

implementation

{ TEngHello }

function TEngHello.Hello(const S: string): string;
begin
  Result := 'Hello, ' + S;
end;

{ TChinaHello }

function TChinaHello.Hello(const S: string): string;
begin
  Result := '你好, ' + S + ', 吃饭了吗?';
end;

{ TMyHello }

constructor TMyHello.Create(AOwner: TComponent);
begin
  inherited;

  FEngHello := TEngHello.Create(AOwner);
  FEngHello.Name := 'EngHello';

  FChinaHello := TChinaHello.Create(AOwner);
  FChinaHello.Name := 'ChinaHello';

  FMyIntf := FEngHello as IMyIntf;
end;

procedure TMyHello.SetMyIndex(const Value: Integer);
begin
  FMyIndex := Value;
  case value of
    0: FMyIntf := FEngHello as IMyIntf;
    1: FMyIntf := FChinaHello as IMyIntf;
  end;
end;

end.


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值