关于接口的多态性问题 接口的实现
2011-09-18 13:40
357 查看
这里关于接口的定义和为什么使用接口不做多说,大家也都知道。
下面主要说一下关于接口的使用过程中关于多态性问题,这个是我比较关注的问题。
接口的限制
不允许在接口中包含任何字段,即使是static字段。
不允许在接口中包含任何构造函数。
不允许在接口中包含任何析构函数。
不允许为接口中的任何方法指定访问修饰符。
不允许在接口中嵌套任何类型。
不允许从结构或者类中继承一个接口,虽然一个接口能从另一个接口继承。
下面给出一个我们即将用到的简单的接口的定义:
注意一个良好的编程习惯: 定义的接口以 I 开头,这样可以清楚的区分接口和其他类。
用于实现一个接口的所有的方法都必须有public 的访问型,但是,如果你是显示的实现接口,则不可以为显示实现的接口指定访问修饰符。
使用显示实现的接口不能声明为 virtual ,但在省略接口名以后则可以声明为virtual.
因为显示实现的接口不能声明为 virtual ,所以显示实现的接口不能实现多态性。但是显示接口的实现有很多优势,可以写出更清晰更容易维护的代码,增强可预测性。如果一个类实现的多个接口中有相同的函数的声明,这样我们只有通过显示的实现接口来避免歧义。
需要注意的一点:显示实现接口以后,这个显示的实现的接口默认具有 public 可访问性,对实现的接口的方法的访问,只能通过接口名来访问,不能通过实现接口类的实例对象来访问,实例对象是找不到显示实现的接口的方法的。只有通过一个接口类型的变量引用实现接口的类的对象,并通过这个接口引用访问类中实现的接口方法。
显示实现的接口:
在 MyWork 这个类中,接口都是显示实现的,在SonOfMyWork中,继承了MyWork, 并且重新声明了 test() 函数。
下面看一下运行结果:
work.test(); 这里通过接口调用方法,输出的结果就是接口的显示实现。
son.test(); 因为son 对象是继承于MyWork , SonOfMyWork 定义的test() 方法已经隐藏了父类的方法,所以调用的是在SonOfMyWork 类中定义的test() 方法。 这里也说明了接口的显示实现不能实现多态性,但是以后在有类继承SonOfMyWork 类的时候,就可以再次将test() 实现多态性。
work = son; work.test(); 这里通过接口访问实现接口类的派生类,用来测试接口的多态性,注意,这里的输出是接口的显示实现中输出的语句,并没有访问到这个派生类中的test() 方法,而是访问的接口的显示实现的类中的方法。
以下是上面程序的输出:
interface test
interface count
////////////////////////////////////////
class : SonOfMyWork
SonOfMyWork, interface explicitly completed.
////////////////////////////////////////////
interface test
请按任意键继续. . .
上面的程序可以看到接口的显示实现不能实现多态性,但是接口的显示实现确实有很多好处,应该注意接口的显示实现。
接口的隐式实现就可以声明为public, virtual 的,并且可以实现多态性。
关于隐式实现的测试代码:
work = son2;work = son2; 通过接口引用实现接口的类的派生类的对象。
输出结果:
/////////////////////////////////////////
Interface implicitly implement.
/////////////////////////////////////////
Interface in SonOfMyWork2
Interface in SonOfMyWork2
请按任意键继续. . .
这里可以看到隐式实现的接口中,通过对象访问test() 方法和通过接口对派生类对象的引用调用test() 方法都有一致的输出,可以证明隐式实现的接口可以实现多态性。
特别说明:对于这个网页排版工具我不是很会用,所以文章写的有点排版乱,以后尽量的用熟这个工具,避免大家看的不舒服。
下面主要说一下关于接口的使用过程中关于多态性问题,这个是我比较关注的问题。
接口的限制
不允许在接口中包含任何字段,即使是static字段。
不允许在接口中包含任何构造函数。
不允许在接口中包含任何析构函数。
不允许为接口中的任何方法指定访问修饰符。
不允许在接口中嵌套任何类型。
不允许从结构或者类中继承一个接口,虽然一个接口能从另一个接口继承。
下面给出一个我们即将用到的简单的接口的定义:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { interface IWork { void test(); int count(int index); } }
注意一个良好的编程习惯: 定义的接口以 I 开头,这样可以清楚的区分接口和其他类。
接口的实现
接口的实现可以分为两种,显示实现接口和非显示的实现接口。显示实现接口
使用接口名做为方法名的前缀,成为显示接口实现,也是我们应该养成的一个编程习惯。(但是我自己的练习中发现显示实现的接口无法实现多态性,可能规定的就不能实现多态性,这点接下来会讲)用于实现一个接口的所有的方法都必须有public 的访问型,但是,如果你是显示的实现接口,则不可以为显示实现的接口指定访问修饰符。
使用显示实现的接口不能声明为 virtual ,但在省略接口名以后则可以声明为virtual.
因为显示实现的接口不能声明为 virtual ,所以显示实现的接口不能实现多态性。但是显示接口的实现有很多优势,可以写出更清晰更容易维护的代码,增强可预测性。如果一个类实现的多个接口中有相同的函数的声明,这样我们只有通过显示的实现接口来避免歧义。
需要注意的一点:显示实现接口以后,这个显示的实现的接口默认具有 public 可访问性,对实现的接口的方法的访问,只能通过接口名来访问,不能通过实现接口类的实例对象来访问,实例对象是找不到显示实现的接口的方法的。只有通过一个接口类型的变量引用实现接口的类的对象,并通过这个接口引用访问类中实现的接口方法。
显示实现的接口:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { class MyWork:IWork { public MyWork() { } void IWork.test() { Console.WriteLine("interface test"); //throw new NotImplementedException(); } int IWork.count(int index) { Console.WriteLine("interface count"); //throw new NotImplementedException(); return 0; } } class SonOfMyWork : MyWork { public SonOfMyWork() : base() { Console.WriteLine("class : SonOfMyWork"); } public virtual void test() { Console.WriteLine("SonOfMyWork, interface explicitly completed."); } } }
在 MyWork 这个类中,接口都是显示实现的,在SonOfMyWork中,继承了MyWork, 并且重新声明了 test() 函数。
下面看一下运行结果:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { MyWork myWork = new MyWork(); IWork work = myWork; work.test(); work.count(5); Console.WriteLine("////////////////////////////////////////"); SonOfMyWork son = new SonOfMyWork(); son.test(); Console.WriteLine("////////////////////////////////////////////"); work = son; work.test(); //Console.WriteLine("/////////////////////////////////////////"); //MyWork2 myWork2 = new MyWork2(); //myWork2.test(); //Console.WriteLine("/////////////////////////////////////////"); //SonOfMyWork2 son2 = new SonOfMyWork2(); //son2.test(); //work = son2; //work.test(); } } }
work.test(); 这里通过接口调用方法,输出的结果就是接口的显示实现。
son.test(); 因为son 对象是继承于MyWork , SonOfMyWork 定义的test() 方法已经隐藏了父类的方法,所以调用的是在SonOfMyWork 类中定义的test() 方法。 这里也说明了接口的显示实现不能实现多态性,但是以后在有类继承SonOfMyWork 类的时候,就可以再次将test() 实现多态性。
work = son; work.test(); 这里通过接口访问实现接口类的派生类,用来测试接口的多态性,注意,这里的输出是接口的显示实现中输出的语句,并没有访问到这个派生类中的test() 方法,而是访问的接口的显示实现的类中的方法。
以下是上面程序的输出:
interface test
interface count
////////////////////////////////////////
class : SonOfMyWork
SonOfMyWork, interface explicitly completed.
////////////////////////////////////////////
interface test
请按任意键继续. . .
上面的程序可以看到接口的显示实现不能实现多态性,但是接口的显示实现确实有很多好处,应该注意接口的显示实现。
接口的隐式实现
下面的类是关于接口的隐式实现:using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { class MyWork2:IWork { public virtual void test() { Console.WriteLine("Interface implicitly implement."); //throw new NotImplementedException(); } public virtual int count(int index) { //throw new NotImplementedException(); return 0; } } class SonOfMyWork2 : MyWork2 { public override void test() { //base.test(); Console.WriteLine("Interface in SonOfMyWork2"); } } }
接口的隐式实现就可以声明为public, virtual 的,并且可以实现多态性。
关于隐式实现的测试代码:
Console.WriteLine("/////////////////////////////////////////"); MyWork2 myWork2 = new MyWork2(); myWork2.test(); Console.WriteLine("/////////////////////////////////////////"); SonOfMyWork2 son2 = new SonOfMyWork2(); son2.test(); work = son2; work.test();
work = son2;work = son2; 通过接口引用实现接口的类的派生类的对象。
输出结果:
/////////////////////////////////////////
Interface implicitly implement.
/////////////////////////////////////////
Interface in SonOfMyWork2
Interface in SonOfMyWork2
请按任意键继续. . .
这里可以看到隐式实现的接口中,通过对象访问test() 方法和通过接口对派生类对象的引用调用test() 方法都有一致的输出,可以证明隐式实现的接口可以实现多态性。
特别说明:对于这个网页排版工具我不是很会用,所以文章写的有点排版乱,以后尽量的用熟这个工具,避免大家看的不舒服。
相关文章推荐
- 在C#开发BHO时,关于IObjectWithsite接口实现问题
- 关于实现Serialable接口的类中的serialVersionUID问题
- 关于接口的实现和继承的问题
- JAVA中关于对象数组是否可以实现Comparable接口和排序问题
- 关于实现Comparable接口重写compareTo方法报错问题
- 【ThinkingInJava】16、关于java的接口与抽象类实现的一个问题!
- 关于接口的实现和继承的问题
- 关于java中继承多接口实现其中同名方法的问题
- 关于UGUI实现拖拽功能的接口(IBeginDragHandler、IEndDragHandler、IDragHandler )需注意的问题
- 关于c#实现计算机音频接口输出固定频率波形的一些问题
- 关于PHP写APP接口的安全问题探讨
- 关于OPC自动化接口编程(OPCDAAuto.dll)几点注意问题
- 关于openstack部分计算节点无法实现热迁移问题描述
- linux关于tcp协议ack的实现--总结和公平性问题
- 关于在使用iframe之后子页面中如何在父级弹窗的问题的具体实现
- 关于C语言实现兑换钱的问题
- 关于接口可以实例化的问题
- 关于使用阿里云服务调用识别身份证图片、营业执照的信息抓取接口的简单实现
- java中实现序列化serializable接口的问题
- 关于RTP时间戳及多媒体通信同步的问题/H264关于RTP协议的实现