Delphi中没有多重继承,但是可以通过接口的方式简介实现多继承。
接口是一个只有函数,没有数据的声明,例如
IMyIntf = interface
function ShowInt: Integer;
function ShowStr: string;
end;
接口函数不需要写virtual,实现接口的类必须实现接口声明中的所有函数。
例如:
TMyComp1 = class(TComponent, IMyIntf)
protected
function ShowInt: Integer; virtual;
function ShowStr: string;
end;
现在从TMyComp1继承一个新的类,这样就不必重新实现IMyIntf接口了。
但是既然是继承一个新的类,可能有些方法与父类不同,
对于父类已经声明为virtual的函数,我们可以通过override重写,
但是对于没有声明为virtual的,怎么办呢?
接口重写可以通过如下形式来实现:
TMyComp2 = class(TMyComp1, IMyIntf)
protected
function ShowInt: Integer; override;
function ShowStr: string;
function ShowStr2: string;
function IMyIntf.ShowStr = ShowStr2;
end;
这样当以接口形式调用ShowStr时,实际上调用的是ShowStr2函数。
下面是完整的测试代码,并给出了测试结果:
测试结果如下:
TestIntf --------------------------------
intf1.ShowInt = 1
intf2.ShowInt = 2
intf3.ShowInt = 33
intf1.ShowStr = MyComp1
intf2.ShowStr = MyCompShowStr2
intf3.ShowStr = MyComp1
TestVirtual ------------------------------
comp1.ShowInt = 1
comp2.ShowInt = 2
comp3.ShowInt = 3
comp1.ShowStr = MyComp1
comp2.ShowStr = MyComp1
comp3.ShowStr = MyComp1
接口是一个只有函数,没有数据的声明,例如
IMyIntf = interface
function ShowInt: Integer;
function ShowStr: string;
end;
接口函数不需要写virtual,实现接口的类必须实现接口声明中的所有函数。
例如:
TMyComp1 = class(TComponent, IMyIntf)
protected
function ShowInt: Integer; virtual;
function ShowStr: string;
end;
现在从TMyComp1继承一个新的类,这样就不必重新实现IMyIntf接口了。
但是既然是继承一个新的类,可能有些方法与父类不同,
对于父类已经声明为virtual的函数,我们可以通过override重写,
但是对于没有声明为virtual的,怎么办呢?
接口重写可以通过如下形式来实现:
TMyComp2 = class(TMyComp1, IMyIntf)
protected
function ShowInt: Integer; override;
function ShowStr: string;
function ShowStr2: string;
function IMyIntf.ShowStr = ShowStr2;
end;
这样当以接口形式调用ShowStr时,实际上调用的是ShowStr2函数。
下面是完整的测试代码,并给出了测试结果:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
mmLog: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure AddLog(Log: string);
procedure AddLogFmt(Fmt: string; const Args: array of const);
procedure TestIntf;
procedure TestVirtual;
end;
IMyIntf = interface
function ShowInt: Integer;
function ShowStr: string;
end;
TMyComp1 = class(TComponent, IMyIntf)
protected
function ShowInt: Integer; virtual;
function ShowStr: string;
end;
TMyComp2 = class(TMyComp1, IMyIntf)
protected
function ShowInt: Integer; override;
function ShowStr: string;
function ShowStr2: string;
function IMyIntf.ShowStr = ShowStr2;
end;
TMyComp3 = class(TMyComp1, IMyIntf)
protected
function ShowInt: Integer; override;
function ShowInt3: Integer;
function IMyIntf.ShowInt = ShowInt3;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AddLog(Log: string);
begin
mmLog.Lines.Add(Log);
end;
procedure TForm1.AddLogFmt(Fmt: string; const Args: array of const);
begin
mmLog.Lines.Add(Format(Fmt, Args));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestIntf;
TestVirtual;
end;
{ TMyComp1 }
function TMyComp1.ShowInt: Integer;
begin
Result := 1;
end;
function TMyComp1.ShowStr: string;
begin
Result := 'MyComp1';
end;
{ TMyComp2 }
function TMyComp2.ShowInt: Integer;
begin
Result := 2;
end;
function TMyComp2.ShowStr: string;
begin
Result := 'MyComp2';
end;
function TMyComp2.ShowStr2: string;
begin
Result := 'MyCompShowStr2';
end;
{ TMyComp3 }
function TMyComp3.ShowInt: Integer;
begin
Result := 3;
end;
function TMyComp3.ShowInt3: Integer;
begin
Result := 33;
end;
procedure TForm1.TestIntf;
var
intf1, intf2, intf3: IMyIntf;
begin
intf1 := TMyComp1.Create(Self);
intf2 := TMyComp2.Create(Self);
intf3 := TMyComp3.Create(Self);
AddLog('TestIntf --------------------------------');
AddLogFmt('intf1.ShowInt = %d', [intf1.ShowInt]);
AddLogFmt('intf2.ShowInt = %d', [intf2.ShowInt]);
AddLogFmt('intf3.ShowInt = %d', [intf3.ShowInt]);
AddLogFmt('intf1.ShowStr = %s', [intf1.ShowStr]);
AddLogFmt('intf2.ShowStr = %s', [intf2.ShowStr]);
AddLogFmt('intf3.ShowStr = %s', [intf3.ShowStr]);
end;
procedure TForm1.TestVirtual;
var
comp1, comp2, comp3: TMyComp1;
begin
comp1 := TMyComp1.Create(Self);
comp2 := TMyComp2.Create(Self);
comp3 := TMyComp3.Create(Self);
AddLog('TestVirtual ------------------------------');
AddLogFmt('comp1.ShowInt = %d', [comp1.ShowInt]);
AddLogFmt('comp2.ShowInt = %d', [comp2.ShowInt]);
AddLogFmt('comp3.ShowInt = %d', [comp3.ShowInt])
AddLogFmt('comp1.ShowStr = %s', [comp1.ShowStr]);
AddLogFmt('comp2.ShowStr = %s', [comp2.ShowStr]);
AddLogFmt('comp3.ShowStr = %s', [comp3.ShowStr]);
end;
end.
测试结果如下:
TestIntf --------------------------------
intf1.ShowInt = 1
intf2.ShowInt = 2
intf3.ShowInt = 33
intf1.ShowStr = MyComp1
intf2.ShowStr = MyCompShowStr2
intf3.ShowStr = MyComp1
TestVirtual ------------------------------
comp1.ShowInt = 1
comp2.ShowInt = 2
comp3.ShowInt = 3
comp1.ShowStr = MyComp1
comp2.ShowStr = MyComp1
comp3.ShowStr = MyComp1