接口把类给包装了。类是应用程序功能的实现,所以必然会导致大而全,而接口是简单的,看看各个接口及其方法,都是很少的。 类喜欢采用深层继承关系,这样一来改变一个父类属性将导致一堆子类属性的更新,但是接口可以申明而不实现,接口是不推荐深层继承的。 我觉得MS对COM的说明是正确的,我们用了接口后可以在对用户隐藏内部实现的情况下同时保护老功能还能使用,这也是光用类难以达到的。因为类就意味着要实现新功能,更改老功能,中间没有用户界面层,这样不利于用户调用与程序内部实现的隐蔽性(不对用户公开内部实现)。
接口内部的类的实现是对用户隐蔽的。把实现与对外接口分开是一个对程序员和用户来说都不错的方案。对程序员来说他可以完全不管用户会看到什么和希望看到什么(用户要求),因为这部分与他无关只与接口有关,他可以以任何自己方式来实现任何一个功能。用户看到的则永远是一个又一个简单的接口(看看windows中的接口,每个都不是特别复杂,方便使用)。
要注意的是接口是不能继承的,虽然在很多编程语言中(如VC和Delphi等)一个接口被说成是从另一个继承的,而且在程序中间也是与其它类的继承简单的写成一样的形式如: IMyInterface2 = class(IMyInterface1, Txxxx) 。但是接口的继承只是表面上的,一切功能还要用类来实现!继承在原来的意义上是要继承代码的实现以进行代码复用的,接口是没有实现的,因此接口的“继承”是假继承。
2、COM, VCL与ActiveX
COM, VCL与ActiveX都是现代OOP编程的产物。它们的目的总的来说都是为了代码复用与程序开发与维护的方便。
1>、VCL
VCL是Inprise(公司的名称)用来包装WinAPI的。我们用可视化的方法把一个又一个的VCL控件放在窗口上面就可以以类的调用格式来调用它的方法,设置它的属性,并利用它的消息响应来进行面向用户响应的开发了。但是VCL只能在Delphi与BCB中间使用,虽然我个人很喜欢它。
2>、COM
COM与其说是一个具体的对象,不如说是一个技术方案。它提供的是一个简单易用的用户界面层的概念,那就是接口(Interface)的概念。一个用户能够从一个COM对象得到的只有接口。COM接口没有构造函数啦,只有COM接口的实现类有构造函数.
3>、ActiveX
ActiveX控件是COM技术的一个具体实现。 作为一个ActiveX控件它要支持与实现一系列接口如IDispatch等等,一个正确的实现了MS对ActiveX控件要求的那些接口的COM 对象就是一个ActiveX控件。ActiveX控件是二进制兼容的,windows系统都支持,一般的编程语言都能在其中使用它。比VCL当然要用的广啦。
3、创建接口的实现类
虽然COM接口没有析构函数,但是在Delphi里面你要用CreateComObject来创建接口的实现类。要创建一个COM对象的实例,最好在dpr文件中间调用,只有这样COM对象才能正确的初始化。
假设有一接口 : ITest = interface
[XXXX-XXXX-XX-XX]
procedure Test1 ;
procedure Test2 ;
end ;
另有一个类实现现了ITest接口
TTest =class (TInterfacedObject , ITest )
procedure Test1 ;
procedure Test2 ;
end;
在客户端:
var
o :TTest ;
inf :ITest ;
begin
o := TTest.create ;
inf := o as ITest ;//或 o.getinterface (ITest,inf);
inf.Test1 ;
inf.Test2 ;
end ;
as :通常使用as操作符从一个接口转换为另外一个接口;as操作符, 对象支持特定的接口(对象不支持接口就错的话,可以拦截错误); as自动调用计数功能;
注意: 不同的接口占据不同的内存部分,不能简单的把一个接口值赋给另外一个接口;
接口实现为独立的方法表(虚方法表(Virtual Method Tables)),该表实现在内存中紧靠VMT的地方;我想问的是Interface inf是如何触发TTest.Test1 和Test2的?是靠名字吗,我猜应该不是,是靠位置吗? 客户只要获取得到了接口指针,就可以使用此COM对象/接口的实际功能。delphi7编译器通过VMT,在机器码中产生从对象取得接口,然后再指定给接口变量的代码。这种使用方法容易出错,而且不合接口与实现分离原则 ,最好是另外设计一个工厂,返回这个ITest接口对象供客户使用