C#接口归纳总结实例详解

C#接口的学习,在编程中,我们经常会用到接口,那什么是接口呢?

接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接口定义中指定的接口成员。

接口使用interface关键字进行定义,可由方法、属性、事件、索引器或这四种成员类型的任意组合构成。

接口的特性:

1.接口类似于抽象基类,不能直接实例化接口;接口中的方法都是抽象方法,实现接口的任何非抽象类型都必须实现接口的所有成员:

当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问。

当隐式实现该接口的成员时,实现的成员可以通过类实例访问,也可以通过接口实例访问,但是实现的成员必须是公有的。

2.接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型、不能包含静态成员。

3.接口成员是自动公开的,且不能包含任何访问修饰符。

4.接口自身可从多个接口继承,类和结构可继承多个接口,但接口不能继承类。

为什么不能指定接口中方法的修饰符?

接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。它们默认为公有方法。

interface IProgram
 {
  void Fun();
 }
 class Program:IProgram
 {
   //显式实现接口成员
  void IProgram.Fun()
  {
   Console.WriteLine("I am Fun.");
  }
  staticvoid Main(string[] args)
  {
   IProgram p =new Program(); //声明一个接口实例,但不是对接口进行实例化
   p.Fun();
   Console.Read();
  }
 }

上面提到,实现接口可以显式实现和隐式实现,那么这两种实现到底有什么优缺点呢?

一般情况,当类或者结构要实现的是单个接口,可以使用隐式实现。

如果类或者结构继承了多个接口且接口中具有相同名称成员时,就要用到显式实现,当显式实现方式存在时,隐式实现方式就失效了。

interface IProgram
 {
  void Fun();
 }
 interface IAProgram
 {
  void Fun();
 }
 class Program : IProgram, IAProgram
 {
  void IProgram.Fun() //显式实现接口IProgram
  {
   Console.WriteLine("I am IProgram Fun.");
  }
  void IAProgram.Fun() //显式实现接口IAProgram
  {
   Console.WriteLine("I am IAProgram Fun.");
  }
  //public void Fun() //隐式实现接口
  //{
  // Console.WriteLine("I am Program Fun.");
  //}
  staticvoid Main(string[] args)
  {
   //IProgram p = new Program();
   //p.Fun();
   //IAProgram ap = new Program();
   //ap.Fun();
   Program pro =new Program();
   ((IProgram)pro).Fun();
   ((IAProgram)pro).Fun();
   Console.Read();
  }
 }

结果为:I am IProgram Fun.

I am IAProgram Fun.

接口的继承:

接口继承和类继承不同:首先,类继承不仅是说明继承,而且也是实现继承;而接口继承只是说明继承。

也就是说,派生类可以继承基类的方法实现,而派生的接口只继承了父接口的成员方法说明,而没有继承父接口的实现,

其次,C#中类继承只允许单继承,但是接口继承允许多继承,一个子接口可以有多个父接口。

接口可以从零或多个接口中继承。从多个接口中继承时,用":"后跟被继承的接口名字,多个接口名之间用","分割。

被继承的接口应该是可以访问得到的,比如从private 类型或internal 类型的接口中继承就是不允许的。

接口不允许直接或间接地从自身继承。和类的继承相似,接口的继承也形成接口之间的层次结构。

interface IProgram
{
 void Fun();
}
interface IAProgram:IProgram
{
}
class Program : IAProgram
{
 void IProgram.Fun()
 {
  Console.WriteLine("I am IProgram Fun.");
 }
 staticvoid Main(string[] args)
 {
  Program pro =new Program();
  ((IAProgram)pro).Fun();
  Console.Read();
 }
}

接口的覆盖:

由于接口的实现没有方法体,抽象方法也没有方法体,那么当我们在接口的实现方法里调用抽象方法时,会如何执行呢?

 interface IProgram
 {
  void Fun();
 }
 abstractclass AProgram : IProgram
 {
  publicabstractvoid AFun();
  void IProgram.Fun()
  {
   AFun();
  }
 }
 class Program:AProgram
 {
  publicoverridevoid AFun()
  {
   Console.WriteLine("I am AProgram.");
  }
  staticvoid Main(string[] args)
  {
   IProgram pro =new Program();
   pro.Fun();
   Console.Read();
  }
 }
//结果:I am Aprogram.

通过断点,可以看到,当执行pro.Fun();时,首先会跳到接口的实现方法里,然后去调用抽象函数的实现方法,当抽象函数的方法实现后,再回到接口的实现方法,直到执行完成。

当我们在实现接口的方法里调用虚函数呢?

interface IProgram
{
 void Fun();
}
class AProgram : IProgram
{
 publicvirtualvoid AFun() //注意这里是虚函数
 {
  Console.WriteLine("I am virtual AFun.");
 }
 void IProgram.Fun()
 {
  AFun();
 }
}
class Program:AProgram
{
 publicoverridevoid AFun() //这里是Override重写
 {
  Console.WriteLine("I am override AFun.");
 }
 staticvoid Main(string[] args)
 {
  IProgram pro =new Program();
  pro.Fun();
  Console.Read();
 }
}

这时,我们发现,执行的顺序和上一个例子是相同的。所以结果为:I am override AFun.

由此,我们可以继续联想,当我们把override关键字,换成new呢?是不是也是同样的结果,还是和我们以前讲的例子一样,是隐藏呢?

我们把上面的例子进行改进

interface IProgram
 {
  void Fun();
 }
 class AProgram : IProgram
 {
  publicvirtualvoid AFun()
  {
   Console.WriteLine("I am virtual AFun.");
  }
  void IProgram.Fun()
  {
   AFun();
  }
 }
 class Program:AProgram
 {
  publicnewvoid AFun()
  {
   Console.WriteLine("I am new AFun.");
  }
  staticvoid Main(string[] args)
  {
   Program pro =new Program();
   ((IProgram)pro).Fun();
   pro.AFun();
   Console.Read();
  }
 }

结果为:I am virtual AFun.

I am new AFun.

由于前面已经讲过了,这里不在对此进行分析,由此我们可知使用New关键字是对其进行隐藏,当对接口实现的方法里调用的是虚方法时,和类的执行过程是一样的。

接口和抽象类的区别。

接口用于规范,抽象类用于共性。

接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。

抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。

抽象类可以提供某些方法的部分实现,接口不可以。

抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。

在抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要重新编写(这就是为什么说接口是一个类的规范了)。

接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。

此外接口不能包含字段、构造函数、析构函数、静态成员或常量。

C#中的接口和类有什么异同。

异:

不能直接实例化接口。

接口不包含方法的实现。

接口可以实现多继承,而类只能是单继承。

类定义可在不同的源文件之间进行拆分。

同:

接口、类和结构可从多个接口继承。

接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。

接口可以包含事件、索引器、方法和属性。

一个类可以实现多个接口。

希望本篇文章对您有所帮助

(0)

相关推荐

  • C# IEnumerable和IEnumerator接口浅析

    温故而知新,可以为师矣,有空经常复习一下基础知识是有必要的,并且能加深理解和记忆. Foreach常用于循环访问集合,对实现IEnumerable的接口的容器进行遍历,IEnumerable和IEnumerator接口我有时候也有点迷糊,按官方的解释,IEnumerable是枚举器接口,IEnumerator是迭代器接口,从字面意思来看相差不大,逐一分析一下. IEnumerable接口 public interface IEnumerable { IEnumerator GetEnumerat

  • C#中抽象类与接口的区别详解

    1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分.或者说,它是面向对象编程体系中的思想精髓之一. 2.接口的本质 接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承).它在形式上可能是如下的样子: interface InterfaceName { void Method1(); void Method2

  • C# 泛型接口的抗变和协变

    1, 泛型接口的协变 如果泛型类型用out关键字标注,泛型接口就是协变的.这也意味着返回类型只能是T. 泛型接口的抗变 如果泛型类型用in关键字标注,泛型接口就是抗变的.这样,接口只能把泛型类型T用作其方法的输入,即方法的参数. 这是泛型接口的抗变和协变的定义,那我们下面来用代码说明,直接上代码, /// <summary> /// 泛型接口 /// </summary> /// <typeparam name="T"></typeparam&

  • C# 实例化接口对象的方法

    在head first 设计模式中 用到了很多很多接口对象 首先澄清一个问题,就是接口不仅可以声明对象,而且可以把对象实例化,还可以当做参数被传入. 一.接口回调 这就是继承中的向上转型.父类 FL=new 子类():只不过这里的父类就是interface接口.(个人认为这里不管是class的override还是interface的重写,都是一样的用法) 可以把实现某一接口类创建的对象的引用赋给该接口声明的接口变量,那么该 接口变量就可以调用被类实现的接口中的方法.实际上,当接口变量调用被类实现

  • C# Rx的主要接口深入理解

    C# Rx的主要接口深入理解 IObservable / IObserver 接口在.NET Framework 4.0基类库中可用,并且它们包含在可以安装在.NET 3.5,Silverlight 3和4以及JavaScript中的包中. IObservable/IObserver Rx将异步和基于事件的数据源公开为基于推送的可观察序列,由.NET Framework 4.0中的新IObservable 接口抽象. 这个IObservable 接口是用于基于拉的,可枚举集合的熟悉的IEnume

  • C#接口归纳总结实例详解

    C#接口的学习,在编程中,我们经常会用到接口,那什么是接口呢? 接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接口定义中指定的接口成员. 接口使用interface关键字进行定义,可由方法.属性.事件.索引器或这四种成员类型的任意组合构成. 接口的特性: 1.接口类似于抽象基类,不能直接实例化接口:接口中的方法都是抽象方法,实现接口的任何非抽象类型都必须实现接口的所有成员: 当显式实现该接口的成员时,实现的成员不能通过类实例访问,只能通过接口实例访问. 当隐式实现该

  • 微信小程序request请求后台接口php的实例详解

    微信小程序request请求后台接口php的实例详解 后台php接口:http://www.vueyun.com/good/info 没有处理数据,直接返回了,具体再根据返回格式处理 public function getGoodInfo(Request $request) { $goods_datas = $this->Resource->get(); return response()->json(['status' => 'success','code' => 200,

  • PHP抽象类与接口的区别实例详解

    本文实例讲述了PHP抽象类与接口的区别.分享给大家供大家参考,具体如下: 抽象类abstract 概念 定义为抽象的类不能被实例化.任何一个类,如果有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的类. 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法,这些方法的访问控制必须喝父类中一样或者更为宽松. 例如,某个抽象方法被声明为proteced,那么子类中的实现,就应该声明为protected或者public,而不能定义为private. 方法的调用方式必须匹配,即类型和所需参数数

  • 使用 Jest 和 Supertest 进行接口端点测试实例详解

    本文实例讲述了使用 Jest 和 Supertest 进行接口端点测试.分享给大家供大家参考,具体如下: 如何创建测试是一件困难的事.网络上有许多关于测试的文章,却从来不告诉你他们是如何开始创建测试的. 所以,今天我将分享我在实际工作中是如何从头开始创建测试的.希望能够对你提供一些灵感. 目录: 使用 Express 创建一个应用 使用 Mongoose 链接 MongoDB 使用 Jest 作为测试框架 为什么使用 Jest 易于使用 wath-mode 非常棒 开始使用 Jest 首先,你需

  • 微信公众号 客服接口的开发实例详解

    微信平台更新之后,发现客服接口不错.研究了下 和大家分享下. 按照官方文档,是向客服接口发送规定的JSon 就可以了. 首先先封装下 JSon 的类: package com.lwz.wx.bean.kf; // 这个是最外层的 也可以说是基类吧. public class Basebean { private String touser; private String msgtype; public String getTouser() { return touser; } public vo

  • JDBC中resutset接口操作实例详解

    本文主要向大家展示JDBC接口中resutset接口的用法实例,下面我们看看具体内容. 1. ResultSet细节1 功能:封锁结果集数据 操作:如何获得(取出)结果 package com.sjx.a; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import org.junit.Test; //1. next方

  • java中的interface接口实例详解

     java中的interface接口实例详解 接口:Java接口是一些方法表征的集合,但是却不会在接口里实现具体的方法. java接口的特点如下: 1.java接口不能被实例化 2.java接口中声明的成员自动被设置为public,所以不存在private成员 3.java接口中不能出现方法的具体实现. 4.实现某个接口就必须要实现里面定义的所有方法. 接下来看一个实现接口的案例: package hello;   interface competer{ //定义接口 void set_comp

  • java 线性表接口的实例详解

    java 线性表接口的实例详解 前言: 线性表是其组成元素间具有线性关系的一种线性结构,对线性表的基本操作主要有插入.删除.查找.替换等,这些操作可以在线性表的任何位置进行.线性表可以采用顺序存储结构和链式存储结构表示. 本接口的类属于dataStructure包的linearList子包.线性表接口LList声明如下,描述线性表的取值.置值.插入.删除等基本操作. package dataStructure.linearList; public interface LList<E> { bo

  • Thinkphp5微信小程序获取用户信息接口的实例详解

    Thinkphp5微信小程序获取用户信息接口的实例详解 首先在官网下载示例代码, 选php的, 这里有个坑 官方的php文件,编码是UTF-8+的, 所以要把文件改为UTF-8 然后在Thinkphp5 extend文件夹下建立Wxxcx命名空间,把官方的几个类文件放进去(这里要注意文件夹名, 命名空间名, 类名的, 大小写,一定要一样,官方的文件名和类名大小写不一样) 然后是自己的thinkphp接口代码: <?php /** * Created by PhpStorm. * User: le

  • 微信小程序 检查接口状态实例详解

    微信小程序 检查接口状态实例详解 实例代码: // 检查接口是否可用 wx.getSetting({ success(res) { if (!res['scope.record']) { // 接口调用询问 wx.authorize({ scope: 'scope.userInfo', success(res) { wx.startRecord() // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 }, fail() { }, complete()

随机推荐