zoukankan      html  css  js  c++  java
  • 接口方法的隐式和显示实现

    先看一段代码,先猜猜下面标注1、2、3、4、5、6、7、8、9、10 的地方的输出情况
    注:使用 Snippet Compiler Live 2008 编辑器

     
     1   public static void RunSnippet()
    2 {
    3 ITest a = new Test();
    4 a.Say(); // 1
    5

    6 a = new App();
    7 a.Say(); // 2
    8

    9 a = new Strong();
    10 a.Say(); // 3
    11

    12 Test t = new Test();
    13 t.Say(); // 4
    14

    15 t = new App();
    16 t.Say(); // 5
    17 ((ITest)t).Say(); // 6
    18

    19 t = new Strong();
    20 t.Say(); // 7
    21 ((ITest)t).Say(); // 8
    22

    23 Strong s = new Strong();
    24 s.Say(); // 9
    25 ((ITest)s).Say(); // 10
    26 }

    27
    28 public class Test : ITest
    29 {
    30 public void Say()
    31 {
    32 Console.WriteLine("Test Says.");
    33 }
    34
    35 void ITest.Say()
    36 {
    37 Console.WriteLine("ITest Says.");
    38 }
    39 }
    40
    41 public class App : Test, ITest
    42 {
    43 new public void Say()
    44 {
    45 Console.WriteLine("App says.");
    46 }
    47 }
    48
    49 public class Strong : Test/*, ITest*/
    50 {
    51 /*
    52 new public void Say()
    53 {
    54 Console.WriteLine("Strong says.");
    55 }
    56 */

    57 }
    58
    59 public interface ITest
    60 {
    61 void Say();
    62 }




    输出结果为:
    1  ITest Says. (接口显示实现,接口类型只调用接口方法)
    2  App Says. (虽然继承Test,但重新继承了接口,并重写了接口方法)
    3  ITest Says. (继承Test,接口显示实现的方法也继承)
    4  Test Says. (Test对象,调用对象方法,而不是接口方法)
    5  Test Says. (为什么不是App Says? 因为App重新实现的是接口方法,而Test中的接口方法是不能重写的,故调用是Test对象的方法)
    6  App says. (为什么不是ITest Says? 因为App实现了接口方法,接口调用的是App实现接口方法,再说Test中的显示接口方法是私有的)
    7  Test Says. (继承的是Test类型的方法)
    8  ITest Says. (接口类型调用显示接口方法)
    9  Test Says. (继承的是Test对象方法)
    10 ITest Says. (接口类型调用显示接口方法)

    为什么会出现上面的结果呢?
       当一个类型实现接口的时候,C#编译时同时生成了一个类型的对象方法和接口方法,他们两个引用的实现是同一个方法。
       当显示实现接口方法,并同时实现类型的对象方法时就区分开来了,并且接口方法的访问属性被编译器生产元数据时指定为私有的,防止类型实例调用。这样显示接口方法只能用接口类型调用,反之,当用接口类型调用方法时,只能调用接口的方法(无论显示还是隐式实现)。
       另一点,显示接口方法是不能被派生类重写的,因为显示接口方法并不属于类型的对象模型的一部分,它是将一个接口(一组行为或方法)连接到一个类型上,同时避免暴露行为/方法的一种方式。

    参考《框架设计(第二版) CLR Via C#》第14张5节(14.5) 接口方法的隐式和显示实现(幕后细节)


  • 相关阅读:
    pycharm运行程序,总是出现IPthony界面(IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 6.2.1)
    《剑指offer》第十一题:旋转数组的最小数字
    《剑指offer》第十题:斐波那契数列
    《剑指offer》第九题:用两个栈实现队列
    《剑指offer》第八题:二叉树的下一个节点
    《剑指offer》第七题:重建二叉树
    《剑指offer》第六题:从尾到头打印链表
    《剑指offer》第五题:替换空格
    《剑指offer》第四题:二维数组中的查找
    《剑指offer》第三题II:不修改数组找出重复的数字
  • 原文地址:https://www.cnblogs.com/ranmofang/p/2275086.html
Copyright © 2011-2022 走看看