CLR不允许继承多个基类,但是可以继承多个接口。凡是能使用具名接口类型的实例的地方,都能使用实现了接口的一个类型的实例。 接口是对一组方法签名进行了统一命名,但不提供任何实现,而具体类则必须为继承的全部接口提供实现。

1. 定义接口

接口是用interface关键字定义对一组方法签名,接口名称一般以字母I开头;而且还可以为接口定义事件、索引器和属性,但禁止定义构造器和实例字段,也不能构造任何静态成员。例如:

public interface IShout
{
    public IShout();//×Error Interfaces cannot contain constructors 
    static void Shout1();//×Error The modifier 'static' is not valid for this item 
    void Shout();
    string Name { get; set; }
}

2. 接口方法

具体的类继承接口后要为接口中定义的方法提供实现。我们首先定义一个接口,然后再定义类来实现该接口。

public interface IIntroduce
     {
         void Shout();
         void Description();
     }

接口方法,即具体类中实现接口中定义的方法,它的实现要注意几点:

  • 接口方法必须是Public;
  • CLR要求将接口方法标记为virtual,否则编译器会自动标记为virtual和sealed。

public class Animal : IIntroduce
    {
        public void Shout()                     //接口方法为标记为virtual 
        {
            Console.WriteLine("Animal Shout.");
        }
        public virtual void Description()  //接口方法标记为virtual 
        {
            Console.WriteLine("Animal Description.");
        }
    }

查看IL代码:

  • 派生类可以使用New关键字为接口提供自己的实现。

public class Dog : Animal
   {
       public override void Description()//重写基类的接口方法 
       {
           Console.WriteLine("Dog Description!");
       }
   }

public class Cat : Animal, IIntroduce
   {
       public override void Description()//重写基类的接口方法 
       {
           Console.WriteLine("Cat Description!");
       }
       new public void Shout()//重新实现接口方法 
       {
           Console.WriteLine("Cat Shout.");
       }
   }

3. 显式接口实现

实现接口有隐式实现和显式实现两种方式。当多个接口中包含名称和签名都相同的方法时,要使用显示接口方法实现。

public interface IDemo1
   {
       void Func();
   }
   public interface IDemo2
   {
       void Func();
   }
   public class Demo : IDemo1, IDemo2
   {
       public void Func()
       {
           Console.WriteLine("Demo.Func()");
       }
       void IDemo1.Func()
       {
           Console.WriteLine("IDemo1.Func()");
       }
       void IDemo2.Func()
       {
           Console.WriteLine("IDemo2.Func()");
       }
   }

class Program
   {
       static void Main(string[] args)
       {
           Demo demo = new Demo();
           demo.Func();//调用Demo类中的公共方法Func()
           ((IDemo1)demo).Func(); //显式调用IDemo1中的Func()
           ((IDemo2)demo).Func(); //显式调用IDemo2中的Func()
           Console.Read();
       }
   }

调用结果:

显式接口实现要注意:

  • 不允许指定访问性,如Public等;查看元数据时会发现它自动标记为Private。
  • 不能标记为virtual。
  • 显式接口应该慎重使用,因为值类型的实例在转型为接口时会发生装箱,而且显式接口方法不能被派生类继承。

4.泛型接口

FCL提供了很多现成的接口如IComparable,同时提供了其泛型接口形式IComparable<T>.这样做能够编译时就检测类型从而提高了类型安全,而且减少了参数向object类型转换的装箱拆箱操作,提高了性能。

int x = 1;

IComparable y = "2";

y.CompareTo(x); //编译通过,运行时错误
IComparable<int> z = 3;
z.CompareTo(x); //编译通过,运行通过

5. 基类vs接口

  • 如果存在IS-A关系使用基类,存在CAN-DO关系,使用接口。
  • 基类实现较容易一些,基类提供的功能派生类一般稍作改动即可;而接口方法则要实现所有成员。
  • 版本控制:向基类添加新方法后派生类可以直接使用;向接口添加新方法后需要修改源代码并重新编译。

转载于:https://www.cnblogs.com/changrulin/p/4778645.html

CLR via C#(17)--接口相关推荐

  1. [CLR via C#]17. 委托

    原文:[CLR via C#]17. 委托 回调函数是一种非常有用的编程机制,它已经存在很多年了.Microsoft .NET Framework通过委托(delegate)来提供一种回调机制.不同于 ...

  2. 基类与接口混合继承的声明问题 [C#, Design] -Allen Lee's Magic

    Updated on Friday, November 19, 2004 Written by Allen Lee 1. 问题初现 今天,查看<接口继承的声明问题>一文的反馈,发现Ninp ...

  3. 《CLR via C#》读书笔记---06 类型和成员基础

    核心知识归纳图 6-1 类型中成员的本质 颜色归一 编译器支持了C#提供的各种各样的类型成员,CLR对其一无所知,都是IL代码 大小不同 不同的类型成员因复杂度不同,编译器映射出的IL代码量也不尽相同 ...

  4. 如何免费对接电影票API接口

    版本修订记录 版本标识 注 释 作 者 日 期 1.0 初始版本 * 2018/11/01 1.1 新增了获取影讯接口 * 2019/02/26 1.2 getFilmList 去除了 cityId ...

  5. 电影票API接口及公众号对接H5

    公众号接入授权地址:https://hp.nldy​‌‌p.com/api/openplatform/aut 打开地址按照流程进行接入即可,接入后有后台管理 目录 概述 3 请求参数构成 3 公共请求 ...

  6. ASP.NET 面试题和答案(不断更新)

    1. 简述 private. protected. public.Friend. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问(只能从其声明上下文 ...

  7. 北京某公司.NET面试题

    试题有关网页 http://www.zuoyefeng.com/html/2006-10/433.htm http://fenxue.cnblogs.com/archive/2005/11/12/27 ...

  8. 给大家提供一些面试常问的问题

    给大家提供一些面试常问的问题 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private :     私有成员, 在类的内部才可以 ...

  9. ASP.NET常见面试题及答案(130题)

    1.C#中 property 与 attribute(抽像类)的区别,他们各有什么用处,这种机制的好处在哪里? 答:property和attribute汉语都称之为属性.不过property是指类向外 ...

  10. C#题目及答案(1)

    1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. protected : 保护成 ...

最新文章

  1. 算法提高 身份证排序
  2. linux游戏欢迎界面,制作Linux登录欢迎界面
  3. 接口隔离原则_设计模式之七大设计原则(上)
  4. 爬虫必须得会的预备知识
  5. ECC密钥结构和密码学基础
  6. arcgis几何修复有作用吗_修复损坏的 shapefile
  7. 巨人网络辟谣史玉柱被警方带走:下午一直在上海总部开会
  8. ctb伺服驱动器说明书_安川伺服驱动器SGDV报警原因及处理措施
  9. 数据库和 MIDP,第二部分:数据映射
  10. STM32F407 窗口看门狗 个人笔记
  11. LaTeX 消除字Font shape `OMX/cmex/m/n‘ in size <10.53937> not available (Font) size <10.95> substituted.
  12. 7. JanusGraph服务
  13. 基于FPGA的中值滤波器设计
  14. 制作Thinkpad五合一WIN7光盘(只要两个小步骤,并附$OEM$资料包下载)
  15. 5-7 六度空间 (30分)
  16. 分享一款实用的太阳能充电电路(室内光照可用)
  17. 文件加密器 java_文件加密器: 使用Java Swing编写的文件加密工具,可批量加密电脑中的文件。兼容Windows和Linux。...
  18. 网络打印机无法接收打印命令
  19. 苹果手机在升级系统时一直显示无服务器,苹果手机一直显示检测更新,怎么办?...
  20. 万国觉醒迁服务器显示该王国还未开放,万国觉醒的定点迁城怎么用?怎么获得定点迁城?...

热门文章

  1. 企业网络推广中关键词“出镜率”高会影响企业网络推广吗?
  2. 浅析网站标题优化该如何进行?
  3. python和java和scala_有没有与python3相当的scala/java收藏。国家
  4. opennms mysql_MySQL用户工具
  5. LeakCanary(一)使用篇
  6. When Cyber Security Meets Machine Learning 机器学习 安全分析 对于安全领域的总结很有用 看未来演进方向...
  7. python中set和frozenset方法和区别
  8. word2vec (一) 简介与训练过程概要
  9. Spark中常用的算法
  10. 为什么倒排索引不采用zlib这样的字典压缩算法——因为没法直接使用啊