• 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#这种处理接口方法同名的方式很自然、合理,用起来比较舒服。

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

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

          四、总结

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

  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/WangShun/p/2784371.html
Copyright © 2020-2023  润新知