property MyImplClass: TMyImplClass read FMyImplClass implements IMyIntece;
procedure IMyIntece.P1 = MyP1;
procedure MyP1;
- 146 -
end;
procedure TMyImplClass.P1;
...
procedure TMyImplClass.P2;
...
procedure TMyClass.MyP1;
...
var
MyClass: TMyClass;
MyIntece: IMyIntece;
begin
MyClass := TMyClass.Create;
MyClass.FMyImplClass := TMyImplClass.Create;
MyIntece := MyClass;
MyIntece.P1; // 调用TMyClass.MyP1;
MyIntece.P2; // 调用TImplClass.P2;
end;
Intece references(接口引用)
Intece references(接口引用)
如果你声明一个接口类型的变量,则它可以引用任何实现这个接口的类实例。这样的变量使你可以调用接口的方法,而不必在编译时知道接口是在哪里实现的。但要注意以下限制:
? 使用接口类型的表达式只能访问接口定义的方法和属性,不能访问实现类的其它成员;
? 一个接口类型的表达式不能引用实现了它的派生接口的类实例,除非这个类(或它继承的类)还明
确实现了此祖先接口。
比如,
type
IAncestor = intece
end;
IDescendant = intece(IAncestor)
procedure P1;
end;
TSomething = class(TIntecedObject, IDescendant)
procedure P1;
procedure P2;
end;
...
var
D: IDescendant;
A: IAncestor;
begin
D := TSomething.Create; // 工作正常!
A := TSomething.Create; // 出错 Object inteces
- 147 -
Object inteces
D.P1;
D.P2;// 工作正常! // 出错
end;
在这个例子中,
? A被声明为IAncestor类型的变量,因为TSomething声明实现的接口中没有列出IAncestor,
TSomething类型的实例不能赋给A。但如果改变TSomething的声明为
TSomething = class(TIntecedObject, IAncestor, IDescendant)
...
那么第一个错误语句将变得可用(A := TSomething.Create;)
D被声明为IDescendant类型的变量,虽然它可以引用Tsomething类型的实例,但我们不能用它访问TSomething的P2方法,因为它不是IDescendant接口的方法。但如果改变D的声明为 ?
D: TSomething;
则第二个错误语句将变为可用。(D.P2;)
接口引用通过引用计数进行管理,它依赖于从IIntece继承的_AddRef和_Release方法。若一个对象只通过接口来引用,我们没必要手动销毁它,当它最后的引用超出范围时,它会自动销毁。
全局类型的接口变量能只被初始化为nil。
要判断一个接口类型的表达式是否引用了一个对象,通过标准函数Assigned来完成。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-23665-110.html
不是坏事
连1900也没有