您的位置:首页 > 编程语言

关于接口的多态性问题 接口的实现

2011-09-18 13:40 357 查看
这里关于接口的定义和为什么使用接口不做多说,大家也都知道。

 

下面主要说一下关于接口的使用过程中关于多态性问题,这个是我比较关注的问题。

 

接口的限制

不允许在接口中包含任何字段,即使是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() 方法都有一致的输出,可以证明隐式实现的接口可以实现多态性。

 

特别说明:对于这个网页排版工具我不是很会用,所以文章写的有点排版乱,以后尽量的用熟这个工具,避免大家看的不舒服。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息