CLR via C#(17)--接口
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关系,使用接口。
- 基类实现较容易一些,基类提供的功能派生类一般稍作改动即可;而接口方法则要实现所有成员。
- 版本控制:向基类添加新方法后派生类可以直接使用;向接口添加新方法后需要修改源代码并重新编译。
CLR via C#(17)--接口的更多相关文章
- [CLR via C#]13. 接口
一.类和接口继承 在Microsoft.Net Framwork中,有一个名为System.Object的类,它定义了4个公共实例方法:ToString, Equals, GetHashCode和Ge ...
- 重温CLR(九) 接口
对于多继承(multiple inheritance)的概念,许多程序员并不陌生,他是指一个类从两个或多个基类派生的能力.例如,假定TransmitData类的作用是发送数据,ReceiveData类 ...
- [CLR via C#]17. 委托
回调函数是一种非常有用的编程机制,它已经存在很多年了.Microsoft .NET Framework通过委托(delegate)来提供一种回调机制.不同于其他平台(比如非托管C++)的回调机 ...
- CLR设计类型之接口
写在前面的话: 写到这一节的时候,CLR设计类型就已经结束了,因为CLR要求的是有一定基础的人看的,所以我们不是从基础类型以及运算符开始的,文章从一开始就讲的是深入面向对象编程 ...
- Java基础教程(17)--接口
就像类一样,接口也是引用类型.它可以包含常量,方法签名,默认方法,静态方法和嵌套类型.在接口中,只有默认方法和静态方法有方法体.但不同于类,接口无法实例化,它只能被类实现或被其他接口继承. 一.定 ...
- 第二十二章 CLR寄宿和AppDomain
1. 概念解析 CLR Hosting(CLR 宿主):初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只不过由于PE ...
- 第22章 CLR寄宿和AppDomain
22.1 CLR寄宿 CLR Hosting(CLR 宿主)的概念:初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只 ...
- ASP.NET常见面试题及答案(130题)
1.C#中 property 与 attribute(抽像类)的区别,他们各有什么用处,这种机制的好处在哪里?答:property和attribute汉语都称之为属性.不过property是指类向外提 ...
- asp.net面试题汇总
1.静态成员和非静态成员的区别? 答: 静态变量使用 static 修饰符进行声明,在类被实例化时创建,通过类进行访问不带有 static 修饰符声明的变量称做非静态变量,在对象被实例化时创建,通过对 ...
- 100道.net面试题
简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. protected : 保护成员,该 ...
随机推荐
- 关于Promise:你可能不知道的6件事
FROM ME : 文章介绍了6个Promise的知识点: 1.then() 返回一个 forked Promise(分叉的 Promise):返回的有两种情况: 2.回调函数应该传递结果:在 pro ...
- iOS 开发笔记 -- 各种细枝末节的知识(水滴石穿)
在此总结整理,遇到的各种的小问题: 1.通过从字典(数组)中取出的NSString的length==0 作为if的判断条件导致的carsh: 由于在字典中通过Key取出值之后直接做了length相关操 ...
- ACCESS延时注入
这也算是个新知识吧.今天遇到个站,实实在在存在注入,但是弄不出字段.本应该可以用便宜注入.但是不知道为什么就是就是弄不出来. 大家如果有兴许可以加学习交流群:281245781 交流一下吧. Payl ...
- php preg_库正则匹配
<?php //preg_库提供的正则 preg_match();//进行正则表达式匹配 /* preg_match (pattern , subject, matches) 参数 描述 pat ...
- ajax 载入html后不能执行其中的js解决方法
事件背景 有一个公用页面需要在多个页面调用,其中涉及到部分js已经写在了公用页面中,通过ajax加载该页面后无法执行其中的js. 解决思路 1. 采用附加一个iframe的方法去执行js,为我等代码洁 ...
- nc 局域网聊天+文件传输(netcat)
nc 局域网聊天+文件传输 nc的全程是netcat,这个工具非常好用. 有时候我们需要在局域网内传送一些文本消息或者文件的时候,通常的做法是安装一些局域网通讯软件,然后来做.其实不必要这样,使用nc ...
- php搜索分页
最近做搜索分页的时候,发现第一页显示正常,点击到下一页的时候,显示结果变成了搜索全部内容. 仔细查看代码,发现当第一次输入关键词,提交到查询控制器的时候,表单提交的关键字不为空,可是点击到下一页的时候 ...
- Ubuntu编译源码程序依赖查找方法
ubuntu平时编译源码程序的时候会提示缺少相关的库或是头文件,可以按照以下两种方法进行查找,然后再安装相应的软件包. 1.使用apt-file查找头文件 安装apt-file sudo apt-ge ...
- 火狐浏览器,关闭ssl v3防护
某些网站,没有及时更新,导致火狐觉得有安全隐患,不给访问. --------------- Hello bcasey9090, go to about:config, copy the next bo ...
- IDEA 进入到项目的系统文件路径
选中项目,单击右键,在弹出的菜单中点击file path