9.9.4 定义接口类(2)
试一试:实现接口类
创建CLR控制台项目Ex9_15,并添加内容如前所示的IContainer.h和Box.h头文件。我们还应该将Ex9_14中Stack.h和GlassBox.h头文件的副本添加到该项目中。最后,将Ex9_15.cpp的内容修改成下面这样:
- // Ex9_15.cpp : main project file.
- // Implementing an interface class
- #include "stdafx.h"
- #include "Box.h" // For Box and IContainer
- #include "GlassBox.h" // For GlassBox (and Box and IContainer)
- #include "Stack.h" // For the stack
class with nested struct Item -
- using namespace System;
-
- int main(array<System::String ^> ^args)
- {
- array<IContainer^>^ containers = { gcnew Box(2.0, 3.0, 4.0),
-
gcnew GlassBox(2.0, 3.0, 4.0), -
gcnew Box(4.0, 5.0, 6.0), -
gcnew GlassBox(4.0, 5.0, 6.0) - };
- Console::WriteLine(L"The array of containers
have the following volumes:"); - for each(IContainer^ container in containers)
- container->ShowVolume(); // Output the volume of a box
-
- Console::WriteLine(L"\nNow pushing the containers on the stack...");
-
- Stack^ stack = gcnew Stack; // Create the stack
- for each(IContainer^ container in containers)
- stack->Push(container);
-
- Console::WriteLine(
- L"Popping the containers off the stack
presents them in reverse order:"); - Object^ item;
- while((item = stack->Pop()) != nullptr)
- safe_cast<IContainer^>(item)->ShowVolume();
-
- Console::WriteLine();
- return 0;
- }
该示例产生下面的输出:
- The array of containers have the following volumes:
- CBox usable volume is 24
- CBox usable volume is 20.4
- CBox usable volume is 120
- CBox usable volume is 102
-
- Now pushing the containers on the stack...
- Popping the containers off the stack presents them in reverse order:
- CBox usable volume is 102
- CBox usable volume is 120
- CBox usable volume is 20.4
- CBox usable volume is 24
示例说明
我们首先创建了一个元素类型为IContainer^的数组,并将数组元素初始化为Box和GlassBox对象的地址:
- array<IContainer^>^ containers = { gcnew Box(2.0, 3.0, 4.0),
- gcnew GlassBox(2.0, 3.0, 4.0),
- gcnew Box(4.0, 5.0, 6.0),
- gcnew GlassBox(4.0, 5.0, 6.0)
- };
Box和GlassBox类实现了IContainer接口,因此我们可以在类型为IContainer句柄的变量中存储这两个类的对象地址。这样做的好处是能够多态地调用IContainer接口类的函数成员。
下面的for each循环输出Box和GlassBox对象的体积:
- for each(IContainer^ container in containers)
- container->ShowVolume(); // Output the volume of a box
该循环体说明多态性在起作用,从输出可以看出,被调用的ShowVolume()函数是container引用的对象所属的特定类型的成员。
我们按照上一个示例的方法,将containers数组的元素压入堆栈。将这些元素弹出堆栈的操作同样类似于上一个示例:
- Object^ item;
- while((item = stack->Pop()) != nullptr)
- safe_cast<IContainer^>(item)->ShowVolume();
循环体表明,我们可以用与强制转换引用类类型时完全相同的方式,使用safe_cast强制转换指向接口类型的句柄。之后,就能使用该句柄多态地调用ShowVolume()函数。
使用接口类不仅可以定义一组表示标准类接口的函数,而且是一种强大的、支持在程序中应用多态性的机制。