zoukankan      html  css  js  c++  java
  • C# 显示接口实现(Explicitly Implement)

    场景:一个类继承2个接口,2个接口都包含同一个名称&参数的方法

    问题:不能起别名,如何兼顾这种情况

    实现要点:Explicitly Implement时,不必加保护级别修饰符;要写上interface;

    Sample

    class InterfaceTest:in1,in2

    {

    string isc="";

    public string isclosed

    {get{return"interfaceIsclosed";}}

    string in2.isclosed

    {get{return isc;}set{isc=value;}}

    }

    public interface in1

    {string isclosed { get; }}

    public interfacein2

    {string isclosed { get; set; }

    }

    static void Main(string[] args)

    {InterfaceTest test = new InterfaceTest();

    ((in2)test).isclosed = "newclosed";

    Console.WriteLine("in1's isclosed:" + test.isclosed + "\n\r");

    Console.WriteLine("in12's isclosed:" + ((in2)test).isclosed);

    Console.ReadLine();

    http://www.winu.cn/space-14160-do-blog-id-24202.html

    前两天在看MSDN里面关于迭代器的内容时,看到了一段代码,对其中接口的实现部分不太理解,其代码大致如下:

    代码片段一

        忽的一看,发现有点不对,类里面怎么有两个GetEnumerator()方法(12行和20行),而且参数都一样(都为空),仅仅只是返回值不同。如果是重载方法的话,理论上来说应该会有编译错误啊,但是把代码拷贝到编译器里面编译了一把,顺利通过编译。

         试了一下,如果去掉第20行的方法IEnumerator IEnumerable.GetEnumerator()则出现编译错误,错误内容如下:

    'GenericPractice.Program.Stack<T>' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'. 'GenericPractice.Program.Stack<T>.GetEnumerator()' cannot implement 'System.Collections.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.IEnumerator'.

         错误信息的意思是说我没有实现接口System.Collections.IEnumerable,因为public IEnumerator<T> GetEnumerator()不能实现IEnumerable的IEnumerator GetEnumerator()方法。

         因为IEnumerator<T>是继承自IEnumerator的。所以我刚开始以为,由于方法名和参数一样,只用实现 IEnumerator<T>中的方法就可以了。后来看了下MSDN知道如果要继承一个接口,则需要实现这个接口的方法以及这个接口的所有父接口的方法。

         我总结了下接口实现的一些内容如下:

         一、接口实现分为显式接口实现和隐式接口实现。

         二者有一些不同,显式实现就是指通过指定接口名来实现方法,隐式实现是指通过一个相同的成员方法来实现接口方法。代码示例如下:

    代码片段二

     显示实现的方法不能直接通过类的实例调用,需要强制转换为接口的实例才能调用。 例如:

    代码片段三

         也就是说,如果是显示实现接口的方法,那么该方法不能作为类的实例的方法来调用,只能在类的内部使用,这也就是为什么显示实现的方法不用加“public”等成员限定符的原因,因为加不加没有任何意义。如果需要调用,需要先把类的实例转换为接口实例再调用。

         另外,在试的过程还发现一个问题,如果类既有隐式实现也有隐式实现接口,那么隐式实现的方法将会被作为类的成员方法,显示实现的方法将会被作为接口的方法。这个结果也很符合常理。

         二、实现多个接口时,各个接口中有完全相同方法的情况。

          如果两个接口IA、IB中有一个完全相同的方法(返回值和参数都要相同,否则会被看成不同的方法),现在我们有一个类要去实现这两个接口,情况如下:

         a. 如果是隐式实现,那么实现一个方法就可以了,这个方法会当作是对两个接口的实现。

         b. 如果是显示实现,那么需要分别实现,各个接口的方法实现是独立的。

          好像Java中不支持这种用法,会给一个编译错误。这也算是C#对Java一个改进的方面吧。具体的C#示例代码如下:


     1 interface IA
     2 {
     3     void fun1();
     4 }
     5 
     6 interface IB
     7 {
     8     void fun1();
     9 }
    10 
    11 //隐式实现接口IA,IB
    12 class ImplicitClass : IA, IB
    13 {
    14     public void fun1()
    15     {
    16         Console.WriteLine("public void fun1()");
    17     }
    18 }
    19 
    20 //显式实现接口IA,IB
    21 class ExplicitClass : IA, IB
    22 {
    23     void IA.fun1()
    24     {
    25         Console.WriteLine("void IA.fun1()");
    26     }
    27 
    28     void IB.fun1()
    29     {
    30         Console.WriteLine("void IB.fun1()");
    31     }
    32 }
    33 
    34 //调用
    35 static void Main(string[] args)
    36 {
    37     //显式实现接口的类的对象
    38     ImplicitClass ImplicitObj = new ImplicitClass();
    39 
    40     //隐式实现接口的类的对象
    41     ExplicitClass ExplicitObj = new ExplicitClass();
    42 
    43     //输出结果为 "public void fun1()"
    44     ImplicitObj.fun1();
    45 
    46     //输出结果为 "public void fun1()"
    47     ((IA)ImplicitObj).fun1();
    48 
    49     //输出结果为 "public void fun1()"
    50     ((IB)ImplicitObj).fun1();
    51 
    52     //输出结果为 "void IA.fun1()"
    53     ((IA)ExplicitObj).fun1();
    54 
    55     //输出结果为 "void IB.fun1()"
    56     ((IB)ExplicitObj).fun1();
    57 }

         还有一种特殊情况,就是如果有隐式实现,并且有部分的显示实现,例如在隐式实现IA的同时类中还给出IB的显示实现。大家应该可以猜的出来,如果是IB的实例来调用方法,那么调用的方法就是IB的显示实现的方法。如果是类的实例来调用方法,那么调用的方法就是类中隐式实现的方法。

         个人觉得C#这种处理接口方法同名的方式很自然、合理,用起来比较舒服。

         三、实现从其它接口派生来的接口,并且该接口与其基类中有完全相同的方法。

          这个和上面的情况非常类似,代码示例就不给出来了,遵循的原则是一样的:类中隐式实现的方法可以由类的实例来调用,如果没有显示的接口实现 ,那么接口的实例同样也可以调用这个隐式实现的方法;如果有显示实现,那么接口的实例调用的将会是显式实现的方法,类的实例不能调用显示实现的方法,但是可以在类的内部使用。

          四、总结

         我自己觉得这些没有太大的实践意义,例如像实现两个有相同方法的接口这种情况,实际工作中几乎不碰到,碰到的话也十有八九是设计的问题。主要是乍得一看不太了解,觉得有些新鲜所以花了点时间看了看,加强一下对语法和面向对象的理解。

  • 相关阅读:
    7.12
    Powerdesigner使用方法
    数据库中float类型字段,转化到前端显示,统一保留两位小数
    【1】直接插入排序
    KMP算法
    ssm框架下web项目,web.xml配置文件的作用
    客户要求输入框要记录下上一次输入的内容
    tomcat启动闪退
    页面第一次加载,JS没有效果,刷新一下就好了
    机器学习,安装python的支持包
  • 原文地址:https://www.cnblogs.com/WangShun/p/2784371.html
Copyright © 2011-2022 走看看