Interface(接口)

(本文转载地址:http://blog.sina.com.cn/s/blog_574c993d0100d59n.html)

介绍:
C#中的接口提供了一种实现运行时的多态。通过接口可以使用相同接口的引用来访问实现相同接口的不同类的方法,其实是使用虚方法通过相同的引用调用相同基础的不同的类。

在开始前先使用简单的短类例子来解释接口的概念,下面的简短的例子显示接口的样子。

P1.cs 程序代码:

 class Demo {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
}
} interface abc {
}

输出:Hello Interfaces

编译运行上面的程序运行程序并显示出期望的结果。这段程序包含一个Demo类程序入门Main()方法中打印“Hello Interfaces”。在上面的程序中还定义了接口abc。abc接口是空的,可以在接口中添加一些元素。

P2.cs 程序代码:

 class Demo {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
}
} interface abc {
int x;
}

输出:P2.cs(11,3): error CS0525: Interfaces cannot contain fields

错误!在C#的接口中不能包含字段例如变量。上面的程序在接口abc中声明了一个整型变量x。编译将会出错。

P3.cs 程序代码:

 class Demo {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
}
} interface abc {
void xyz() {
System.Console.WriteLine("In xyz");
}
}

输出:P3.cs(11,8): error CS0531: 'abc.xyz()': interface members cannot have a definition

这次在接口中定义了xyz()方法C#编译器发现了错误。这说明在接口中成员不能有定义。也就意味着如果在接口abc中仅仅只有方法的声明编译器将认为正确?

P4.cs 程序代码:

 class Demo {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
}
} interface abc {
void xyz();
}

输出:Hello Interfaces

上面的程序编译运行正常产生期望的输出结果。最后编译成功。在C#的接口中仅仅包含方法的定义。现在看看方法的作用。接口是类实现的规范。也就是说接口规定了方法的原型并有类来实现接口所定义的方法原型。
因此在类Demo和接口abc结合在一起。

P5.cs 程序代码:

 class Demo : abc {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
}
} interface abc {
void xyz();
}

输出:

P4.cs(1,7): error CS0535: 'Demo' does not implement interface member 'abc.xyz()'
P4.cs(11,8): (Location of symbol related to previous error)

在上面的代码中Demo和接口abc通过“demo : abc”联系在一起,通常对于这个结合有一点小的误会。类Demo需要负责定义接口abc中定义的方法原型。因此在上面代码中的Demo没有实现abc接口中定义的xyz的方法,上面的代码出错。为了修正问题,类Demo必须实现接口abc中定义的方法原型xyz。看下面的程序代码。

P6.cs 程序代码:

 class Demo : abc {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
} void xyz() {
System.Console.WriteLine("In xyz");
}
} interface abc {
void xyz();
}

输出:

a.cs(1,7): error CS0536: 'Demo' does not implement interface member 'abc.xyz()'.'Demo.xyz()' is either static, not public, or has  the wrong return type.
a.cs(16,8): (Location of symbol related to previous error)
a.cs(7,8): (Location of symbol related to previous error)

又出现错误!类Demo实现了方法xyz但没有足够的访问权限。在接口abc定义的方法xyz的访问权限是public。看下面的代码。

P7.cs 程序代码:

   class Demo : abc {
public static void Main() {
Demo demo = new Demo();
System.Console.WriteLine("Hello Interfaces");
demo.xyz();
} public void xyz() {
System.Console.WriteLine("In xyz");
}
} interface abc {
void xyz();
}

输出:

Hello Interfaces
In xyz

好的!上面的代码编译运行成功产生预期的输出结果。正如前面提及的接口可以调用实现相同的接口的不同的类。因此,需要不同的实现相同接口的类。在上面的代码中类Demo实现了接口abc。下面让另一个类Sample也实现接口abc。

P8.cs 程序代码:

 class Demo : abc {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
refDemo.xyz();
Sample refSample = new Sample();
refSample.xyz();
} public void xyz() {
System.Console.WriteLine("In Demo :: xyz");
}
} interface abc {
void xyz();
} class Sample : abc {
public void xyz() {
System.Console.WriteLine("In Sample :: xyz");
}
}

输出:

In Demo :: xyz
In Sample :: xyz

上面的程序编译运行成功生产期望的输出结果。refDemo是类Demo的实例。refSample是类Sample的实例。这两个类都实现了接口abc因此他们都实现了方法xyz()。从程序入口Main()方法中通过refDemo和refSample实例分别调用了类Demo和类Sample的xyz()方法。
现在有两个不同的类实现了相同的接口此时显示了如何从不同的类中使用相同的接口引用。

P9.cs  程序代码:

 class Demo : abc {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
abc refabc = null;
refabc = new Demo();
refabc.xyz();
refabc = new Sample();
refabc.xyz();
} public void xyz() {
System.Console.WriteLine("In Demo :: xyz");
}
} interface abc {
void xyz();
} class Sample : abc {
public void xyz() {
System.Console.WriteLine("In Sample :: xyz");
}
}

输出:

In Demo :: xyz
In Sample :: xyz

上面的代码编译运行程序产生了预期的输出结果。在Main()方法中定义了接口引用refabc是接口abc类型。实例化为Demo在refabc中存储了类Demo类定义的xyz()可以通过refabc来调用。接下去,实例化为Sample在refabc中存储了类Sample类定义的xyz()可以通过refabc来调用。因此,可以通过共同的接口引用refabc来访问不同的类Demo和Sample中的xyz()的方法。在下面的代码中使用循环调用类Demo和Sample实现相同接口abc使用单一接口引用refabc类型匹配的接口abc的类的实现。

P10.cs  程序代码:

 class Demo : abc {
public static void Main() {
abc[] refabc = { new Demo(), new Sample() };
for(int i = ; i <= ; i++)
refabc[i].xyz();
} public void xyz() {
System.Console.WriteLine("In Demo :: xyz");
}
} interface abc {
void xyz();
} class Sample : abc {
public void xyz() {
System.Console.WriteLine("In Sample :: xyz");
}
}

输出:

In Demo :: xyz
In Sample :: xyz

上面的代码编译运行程序产生了预期的输出结果。refabc是一个类型为abc接口的数组。它保存了类Demo和Sample的对象的引用。在for循环中,使用数字refabc,可以调用类Demo和Sample中的方法xyz()。一个类可以实现多个接口。看下面的程序。

P11.cs 程序代码:

 class Demo : abc, def {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
abc refabc = new Demo();
refabc.xyz();
} public void xyz() {
System.Console.WriteLine("In xyz");
} public void pqr() {
System.Console.WriteLine("In xyz");
}
} interface abc {
void xyz();
} interface def {
void pqr();
}

输出:

Hello Interfaces
In xyz

上面的代码编译运行程序产生了预期的输出结果。类Demo实现了接口abc并且实现了xyz()方法。类Demo也实现了def接口也实现了pqr()方法。refabc是类型为abc接口的变量是类Demo的实例。可以通过refabc的实例调用Demo中xyz()方法就像refabc是接口abc的类型包含了xyz()方法的原型

P12.cs 程序代码:

 class Demo : abc, def {
public static void Main() {
System.Console.WriteLine("Hello Interfaces");
abc refabc = new Demo();
refabc.xyz();
refabc.pqr();
} public void xyz() {
System.Console.WriteLine("In xyz");
} public void pqr() {
System.Console.WriteLine("In xyz");
}
} interface abc {
void xyz();
} interface def {
void pqr();
}

输出:

P11.cs(9,5): error CS0117: 'abc' does not contain a definition for 'pqr'

错误!尝试通过定义为接口abc类型的变量refabc的Demo实例来访问pqr()方法,在接口abc中包含了函数xyz()的原型但没有包含pqr()方法原型。可以通过类型为接口def的Demo实例来方法pqr()方法因为接口def包含方法pqr()的原型。

C# interface (接口基础知识详解)的更多相关文章

  1. RabbitMQ基础知识详解

    什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取队列中 ...

  2. Cisco路由技术基础知识详解

    第一部分 请写出568A的线序(接触网络第一天就应该会的,只要你掐过,想都能想出来) .网卡MAC地址长度是(  )个二进制位(16进制与2进制的换算关系,只是换种方式问,不用你拿笔去算) A.12  ...

  3. RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙

    消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...

  4. Python基础知识详解 从入门到精通(七)类与对象

    本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详 ...

  5. 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)

    在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...

  6. Thrift入门初探(2)--thrift基础知识详解

    昨天总结了thrift的安装和入门实例,Thrift入门初探--thrift安装及java入门实例,今天开始总结一下thrift的相关基础知识. Thrift使用一种中间语言IDL,来进行接口的定义, ...

  7. 直播一:H.264编码基础知识详解

    一.编码基础概念 1.为什么要进行视频编码? 视频是由一帧帧图像组成,就如常见的gif图片,如果打开一张gif图片,可以发现里面是由很多张图片组成.一般视频为了不让观众感觉到卡顿,一秒钟至少需要16帧 ...

  8. 第157天:canvas基础知识详解

    目录 一.canvas简介 1.1 什么是canvas?(了解) 1.2 canvas主要应用的领域(了解) 二.canvas绘图基础 2.0 sublime配置canvas插件(推荐) 2.1 Ca ...

  9. 消息队列RabbitMQ基础知识详解

    一: 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序或者模块对模块的通信方法.MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另 ...

随机推荐

  1. CM集群管理

    用CM装完cdh 版本后,将不同机架的服务器已经认为拆掉网线,但是主机管理那边还是显示已经下载的服务器存在. 如图: 该怎么配置 node8 和node9会自动消失:     DataNode已经显示 ...

  2. 【转】深入理解Linux修改hostname

    当我觉得对Linux系统下修改hostname已经非常熟悉的时候,今天碰到了几个个问题,这几个问题给我好好上了一课,很多知识点,当你觉得你已经掌握的时候,其实你了解的还只是皮毛.技术活,切勿浅尝则止! ...

  3. 教你如何有效防止DDos攻击?

    DDos又称分布式拒绝服务,DDos是利用大量合理的请求造成资源过载,导致服务不可用.就比如一个餐馆总共有100个座位,突然有一天某个商家恶意竞争,雇佣了200个人来到这个餐馆坐着不吃不喝,门口还排着 ...

  4. nuxt 利用lru-cache 做服务器数据请求缓存

    // 运行与服务端的js // node.js lru-cache import LRU from 'lru-cache' const lruCache = LRU({ // 缓存队列长度 max: ...

  5. nuxt header 设置

    1. nuxt.config.js 中配置全局 2. 在单页面设置单独

  6. Windows下Cython使用(VS2017)

    收到公众号推送文章“利用Cython为Python代码加速”后尝试在Windows平台下使用Cython,环境为Python3.5 + VS2017. 1. 简单尝试 1)新建hello.pyx文件, ...

  7. 结对编程UI

    GitHub:https://github.com/zsl1996/UI/commits/master 一.            实验内容 这是交付给最终用户的软件,有一定的界面和必要的辅助功能.完 ...

  8. 2019牛客暑期多校训练营(第六场)Palindrome Mouse 回文树+dfs

    题目传送门 题意:给出一个字符串,将字符串中所有的回文子串全部放入一个集合里,去重后.问这个集合里有几对<a,b>,使得a是b的子串. 思路:一开始想偏了,以为只要求每个回文串的回文后缀的 ...

  9. ie兼容小知识点

    1.ie的滤镜特别针对ie使用css3的使用 (1)从css3渐变:filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=# ...

  10. 使用Socket.IO做单页SPA应用更新

    单页应用的挑战之一是确保客户端软件和服务器应用相匹配. 举例:如果一个用Bobbie在他的浏览器中加载我们的单页应用,五分钟之后我们更新了服务器应用.现在Bobbiede遇到了问题,因为我们对服务器做 ...