使用显式接口成员执行体通常有两个目的:
1、因为显式接口成员执行体不能通过类的实例进行访问,这就可以从公有接口中把接口的实现部分单独分离开。如果一个类只在内部使用该接口,而类的使用者不会直接使用到该接口,这种显式接口成员执行体就可以起到作用。
2、显式接口成员执行体避免了接口成员之间因为同名而发生混淆。如果一个类希望对名称和返回类型相同的接口成员采用不同的实现方式,这就必须要使用到显式接口成员执行体。如果没有显式接口成员执行体,那么对于名称和返回类型不同的接口成员,类也无法进行实现。
下面的定义是无效的,因为shape 定义时基类列表中没有出现接口icomparable。
| class shape: icloneable { object icloneable.clone( ) {…} } class ellipse: shape { object icloneable.clone( ) {…} } |
在ellipse 中定义icloneable.clone是错误的,因为ellipse即使隐式地实现了接口icloneable,icloneable仍然没有显式地出现在ellipse定义的基类列表中。
接口成员的全权名必须对应在接口中定义的成员。如下面的例子中,paint的显式接口成员执行体必须写成icontrol.paint。
| using system ; interface icontrol { void paint( ) ; } interface itextbox: icontrol { void settext(string text) ; } class textbox: itextbox { void icontrol.paint( ) {…} void itextbox.settext(string text) {…} } |
实现接口的类可以显式实现该接口的成员。当显式实现某成员时,不能通过类实例访问该成员,而只能通过该接口的实例访问该成员。显式接口实现还允许程序员继承共享相同成员名的两个接口,并为每个接口成员提供一个单独的实现。
下面例子中同时以公制单位和英制单位显示框的尺寸。box类继承 ienglishdimensions和 imetricdimensions两个接口,它们表示不同的度量衡系统。两个接口有相同的成员名 length 和 width。
程序清单1 demoninterface.cs
| interface ienglishdimensions { float length ( ) ; float width ( ) ; } interface imetricdimensions { float length ( ) ; float width ( ) ; } class box : ienglishdimensions, imetricdimensions { float lengthinches ; float widthinches ; public box(float length, float width) { lengthinches = length ; widthinches = width ; } float ienglishdimensions.length( ) { return lengthinches ; } float ienglishdimensions.width( ) { return widthinches ; } float imetricdimensions.length( ) { return lengthinches * 2.54f ; } float imetricdimensions.width( ) { return widthinches * 2.54f ; } public static void main( ) { //定义一个实类对象 "mybox":: box mybox = new box(30.0f, 20.0f); // 定义一个接口" edimensions":: ienglishdimensions edimensions = (ienglishdimensions) mybox; imetricdimensions mdimensions = (imetricdimensions) mybox; // 输出: system.console.writeline(" length(in): {0}", edimensions.length( )); system.console.writeline(" width (in): {0}", edimensions.width( )); system.console.writeline(" length(cm): {0}", mdimensions.length( )); system.console.writeline(" width (cm): {0}", mdimensions.width( )); } } |
输出:length(in): 30,width (in): 20,length(cm): 76.2,width (cm): 50.8
代码讨论:如果希望默认度量采用英制单位,请正常实现 length 和 width 这两个方法,并从 imetricdimensions 接口显式实现 length 和 width 方法:
| public float length( ) { return lengthinches ; } public float width( ){ return widthinches; } float imetricdimensions.length( ) { return lengthinches * 2.54f ; } float imetricdimensions.width( ) { return widthinches * 2.54f ; } |
这种情况下,可以从类实例访问英制单位,而从接口实例访问公制单位:
| system.console.writeline("length(in): {0}", mybox.length( )) ; system.console.writeline("width (in): {0}", mybox.width( )) ; system.console.writeline("length(cm): {0}", mdimensions.length( )) ; system.console.writeline("width (cm): {0}", mdimensions.width( )) ; |