读书人

兑现了派生interface的对象不支持基in

发布时间: 2013-03-16 11:51:46 作者: rapoo

实现了派生interface的对象不支持基interface
本帖最后由 kingyo 于 2013-02-02 20:59:17 编辑 有一个基接口IBase,一个派生接口IDerive,一个类实现了派生接口,是无法直接从该类对象中获得基接口的。例如:


type
IBase = interface
['{87698B00-30FC-49F6-9CAE-F8DE39773D94}']
end;

IDerive = interface(IBase)
['{FB597533-3125-41B6-94D7-53A871097635}']
end;

TMyObj = class(TInterfacedObject, IDerive)
end;

procedure DoSome;
var
o : TMyObject;
ib : IBase;
begin
o := TMyObject.Create;
ib := o; //Compile error!
ib := o as IBase; //Runtime error!
end;

既然IDerive从IBase继承,那么TMyObject实现了IDerive当然就实现了IBase,为什么到基接口的转换不可以呢?我想编译器拒绝这么做应该有一定的道理,但是我不知道原因。
我觉得

TMyObj = class(TInterfacedObject, IDerive)
TMyObj = class(TInterfacedObject, IBase, IDerive) //非得这么写?


[解决办法]
引用:
我知道将TMyObject赋值给IDerived是可以的,也知道将TMyObject赋值给IBase是不可以的,我想知道为什么不可以。


回答一下你最开始的提问, 见代码注释
unit Unit13;

interface

type
IBase = interface
['{87698B00-30FC-49F6-9CAE-F8DE39773D94}']
procedure ProcA;
end;

IDerive = interface(IBase)
['{FB597533-3125-41B6-94D7-53A871097635}']
procedure ProcB;
end;

TMyObj = class(TInterfacedObject, IDerive)
public
procedure ProcA;
procedure ProcB;
procedure ProcC;
end;
procedure DoSome;
implementation

procedure DoSome;
var
o : TMyObj;
Base : IBase;
Derive : IDerive;
begin
o := TMyObj.Create;
try
o.ProcA;
o.ProcB;
o.ProcC;

//以下两句无法通行, 因为TMyObj的接口不直接包含IBase, 无法越级向上转换. 和对象的向上转换不同.
{Base := IBase(o);
IBase(o).ProcA;
}

//下边的就可以通行
//////////////////////////////////////
/// IDerive是TMyObj的直接声明接口
IDerive(o).ProcA;
IDerive(o).ProcB;

Derive := IDerive(o);
Derive.ProcA;
Derive.ProcB;

/// 可以通过多次转换达到目的--IBase
IBase(IDerive(o)).ProcA;

Base := IDerive(o);
Base.ProcA;

finally
o.Free;
end;
end;
{ TMyObj }

procedure TMyObj.ProcA;
begin

end;

procedure TMyObj.ProcB;
begin

end;

procedure TMyObj.ProcC;
begin



end;

end.

读书人网 >.NET

热点推荐