俗话说,听说不等于明白,明白不等于会用。对于接口,恐怕对于很多人都一提就知,一看就会,一用就蒙。尤其是搞不明白它和虚类继承之间的区别。
这里给大家一个比较形象点的例子来说明一下它们的区别(看完再扔西红柿,谢谢)
人以食为天嘛,这里就拿这个吃来做例子
一个人可以吃很多东西,主食、水果、蔬菜等等,这些都是可以吃的食物,每种食物都有相应的吃法,所以对于一个人类和食物的定义暂时如下:
人 = class
{
public eat( Tfood food)
{
food.doEat; //开始吃
}
}
食物 = class Abstract
{
public virtual doEat(); //派生类实现
}
主食 = class(食物 )
{
public override doEat()
{
//用相应吃法开吃
}
}
水果 = class(食物 )
{
public override doEat()
{
//用相应吃法开吃
}
蔬菜 = class(食物 )
{
public override doEat()
{
//用相应吃法开吃
}
这样,如果一个人要吃东西,就要这样实现:
人类 人 = new 人类();
水果 一个水果 = new 水果();
…..
人.eat(一个水果 );
OK,使用虚类的多态,可以通过继承食物类来让人吃任何食物。
但是,再往下,这个人生病了,需要吃药,那这个方法怎么来实现,同样让药来继承自食物??…等等,估计除了病秧子,没人拿药来当作食物吧,原来的方法没法用了。
也许有人会想,可以在食物类上再抽象一个可食用类吧,嗯,能这样想很好,于是你抽象出来另一个上层类。
好,我们继续,这人吧,是社会化动物,既然如此,那免不了跟人交流,那么也免不了吃亏,呵呵,问题来了,这个亏是个什么可食用类呢?有核没核,有籽没籽?实在难说,我们也不会为此再为可食用类构造更高一层的抽象类吧?如果这样无休止的抽象下去,我想你快成盘古了(持续2秒的笑)
OK,说到这,也应该让我们的救世主出场了。
接口,我想大家对它可以说是耳熟能详了,它的优点我们都几乎能倒背如流。那么好,让我们来看看它真正的威力。
我们把上面的例子改一下:
我们不用食物类作为虚类,而是定义一个食用接口ICanEat,其中包含了一个吃法doEat
ICanEat = Interface
{
doEat();
}
然后让所有能够让人吃的对象都实现这个接口(代码略)
最后把人类中吃东西的方法也加以修改:
public eat( ICanEat ob)
{
ob.doEat; //开始吃
}
好的,到现在,人可以吃任何继承自ICanEat接口的对象了,只要提供吃法,他就可以尽情享用。
到这,大家应该看出接口相比虚类继承的优势了
1、轻型继承和多种实现继承。接口可以不附带任何与之无关的实现(虚类继承的子类带有父类的所有实现),而且接口可以实现多继承(类的多继承在DELPHI、JAVA和C#里是不允许的)。
2、接口可以让毫不相干的类组合到一起,从而实现同种目的
3、接口隐藏了具体的实现,只要结果,不要过程