03.Delphi通过接口实现多重继承的优化
阅读原文时间:2023年07月11日阅读:2

在上一篇02中,写到的sayhello函数,需要使用2个接口参数,很繁琐。可以使用as参数,把多重继承的子类对象变成需要的对象

uSayHello代码如下

unit uSayHello;

interface

type
// 接口
IGreetable = interface
['{D91DDE09-0FC4-4FE9-AE0D-9877E2F73BF6}']
// 输出函数
function SayHello: string;
end;

// TInterfacedObject实现了接口的默认方法
TMan = class(TInterfacedObject)
// 语言,姓名,皮肤颜色 属性
Language: string;
Name: string;
SkinColor: string;
public
// 虚方法virtual, 子类需要使用override来覆盖
constructor create; virtual;
end;

// 通过接口,继承了TMan的Create同时也继承了TGreetable的SayHello
TChinese = class(TMan, IGreetable)
public
constructor create; override;
private
function SayHello: string;
end;

TAmerican = class(TMan, IGreetable)
public
constructor create; override;
private
function SayHello: string;
end;

TFrench = class(TMan, IGreetable)
public
constructor create; override;
private
function SayHello: string;
end;

TKorean = class(TMan, IGreetable)
public
constructor create; override;
private
function SayHello: string;
end;

implementation

constructor TMan.create;
begin
Name := '张三';
Language := '中文';
SkinColor := '黄色';
end;

constructor TChinese.create;
begin
inherited;
end;

constructor TAmerican.create;
begin
Name := 'Lee';
Language := '英文';
SkinColor := '黑色';
end;

constructor TFrench.create;
begin
Name := '苏菲';
Language := '法文';
SkinColor := '白色';
end;

constructor TKorean.create;
begin
Name := '金知中';
Language := '韩文';
SkinColor := '黄色';
end;

function TChinese.SayHello;
begin
Result := 'chinese.bmp';
end;

function TAmerican.SayHello;
begin
Result := 'American.bmp';
end;

function TFrench.SayHello;
begin
Result := 'French.bmp';
end;

function TKorean.SayHello;
begin
Result := 'Korean.bmp';
end;

end.

ufrmSayHello代码如下

unit ufrmSayHello;

interface

uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
uSayHello;

type
TfrmSayHello = class(TForm)
GroupBox1: TGroupBox;
edtName: TLabeledEdit;
edtSkinColor: TLabeledEdit;
edtLanguage: TLabeledEdit;
btnUSA: TButton;
btnKorean: TButton;
btnCN: TButton;
btnFrench: TButton;
Image1: TImage;
procedure btnUSAClick(Sender: TObject);
procedure btnCNClick(Sender: TObject);
procedure btnFrenchClick(Sender: TObject);
procedure btnKoreanClick(Sender: TObject);

private
procedure sayhello(AMan: TMan);
public
{ Public declarations }
end;

var
frmSayHello: TfrmSayHello;

implementation

{$R *.dfm}

// 多个不同参数的函数,集成到了一个
procedure TfrmSayHello.sayhello(AMan: TMan);
var
G: IGreetable;
begin
// 类实现的多态
edtName.Text := AMan.Name;
edtLanguage.Text := AMan.Language;
edtSkinColor.Text := AMan.SkinColor;
// as把某个类型对象转换成所需要的类型。 is是判断某对象是否是某类型。
G := AMan as IGreetable;
// 接口实现的多态
Image1.Picture.LoadFromFile(G.sayhello);
end;

procedure TfrmSayHello.btnUSAClick(Sender: TObject);
begin
// sayhello参数定义的父内,传入时传的子类,
sayhello(TAmerican.create);
end;

procedure TfrmSayHello.btnCNClick(Sender: TObject);
begin
sayhello(TChinese.create);
end;

procedure TfrmSayHello.btnFrenchClick(Sender: TObject);
begin
sayhello(TFrench.create);
end;

procedure TfrmSayHello.btnKoreanClick(Sender: TObject);
begin
sayhello(TKorean.create);
end;

end.