2024年3月21日发(作者:)

双重接口

COM Interface Types

COM接口类型

COM内可以定义这三种接口:

● 自定义接口

● 调度接口

● 双重接口

Custom Interfaces

自定义接口

使用自定义接口时,由接口定义的那些方法都被定义在一个vtable中。对于vtable来说,只有那些方法入口才是有用的。

方法的顺序被定义在接口中。

图4-4展示了一个自定义接口。自定义接口总是从接口IUnknown派生。IUnknwon是所有COM接口的基础接口,定义了

三个方法:AddRef、Release和QueryInterface。跟着这些方法之后的是指向接口ICourseManagement所包含方法(GetCourse、

SetCourse和GetCustomerControl)的指针。

图4-4 自定义接口的列表(/bookfiles/179/img/)

这种接口的特点在于这是调用方法最快的途径,但是它会受限于编程语言,接口定义必须在编译时可见。脚本客户端(比

如VBScript和JavaScript)无法使用这些接口,而Visual Basic 6编写的客户端可以使用这种接口

Dispatch Interfaces

调度接口

脚本客户端不能处理自定义接口,它们只能使用调度接口。一个调度接口是一个

IDispatch接口的实现,它可以被脚本客户端理解,所以在编译时不需要知道接口的内存布局。

图4-5展示了IDispatch接口的功能。除了IUnknown的方法外,一个IDispatch接口定义了四个方法。第三个和第四个是

最有意思的方法:GetIDsOfNames和Invoke。GetIDsOfNames会被客户端最先调用以得到一个方法名对应的ID。比如,客户

端传入方法名“GetCourse”后将在返回值中得到其ID 0x60020000。这个方法的标号或者调度ID将会被传入到IDispath的Invoke

方法,以调用GetCourse这个方法。Invoke方法然后就会使用另一个映射表来根据调度ID得到方法入口,这样这个方法就可

以被调用。

你可以想象到这会比自定义接口慢。从方法名获得其ID,以及通过ID调用方法的这些映射机制是需要花时间的。而且除了

这种映射机制,还有数据转换的过程。Invoke仅接受一个参数,这个参数内包含的参数需要通过转换才能用来调用目标方法。

图4-5 调度方法的一个表格/bookfiles/179/img/

Dual Interfaces

双重接口

自定义接口可以提供最佳的性能,而调度接口可以被脚本客户端调用。为了两全其美,微软设计出了双重接口。双重接口

从IDispatch接口派生,但是添加了一些新的方法到vtable中(见图4-6)。只知道IDispatch的客户端可以使用它的

GetIDsOfNames和Invoke方法来得到和访问那些方法指针,但是可以访问自定义接口的客户端也可以直接使用它们。

图4-6 一个双重接口的列表/bookfiles/179/img/

C#中抽象类和接口的区别

一、抽象类:

抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类

可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,

派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不

覆盖,如果不覆盖,则其派生类必须覆盖它们。

二、接口:

接口是引用类型的,类似于类,和抽象类的相似之处有三点:

1、不能实例化;

2、包含未实现的方法声明;

3、派生类必须实现未实现的方法——抽象类是抽象方法,接口则是所有成员(不仅是方法包括

其他成员);

另外,接口有如下特性:

接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为

公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成

员。C#中一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

三、抽象类和接口的区别: