Mail to Keith Dan
keith的天空
海阔凭鱼跃,天高任鸟飞
好象这是一个老生常谈的问题,最近有个学生问我他们的区别,于是我就又想起这个话题。

有不少的文章在描述这两者,但好象都没有怎么从初学者的浅显角度来看。

其实这两者有很多相识之处,当然也有很多不同之处。要理解它们,应该先从面向对象思想开始。面向对象思想里面,最基本的就是封装,继承和多态。所谓封装,说的小,方法(函数)也就是对一种操作的封装,说的大,用类来描述一个具体的对象。

那么在面向对象程序中应该说对封装还有一层新的定义,即将类的描述抽象化,也就是说描述类的外貌而不去考虑它的实际。

那么我们回过头来看抽象类,它必须被继承使用,描述的其实是一种继承关系,即"is a"的关系。类继承它,也就是说类拥有它所有抽象方法等,那么也就是类遵循了它所定义的规范。但是呢,这种规范是通过继承而来,类的发展必须依赖它的父类。

abstract class 工作
{
      
abstract void 上班()
}

class 张三 : 工作{}

abstract class 工作
{
      
abstract void 上班()
}


class 人: 工作{}
class 李四 : 人{}

我们从这个例子中不难看出,张三和李四同样都遵循抽象工作的规范,都拥有上班这个方法,但是呢,他们的发展始终受到父类的影响。

当然,我这里只是从它们使用的角度来看,我们还能从他们设计角度度来看。上面我们虽然实现了人.上班()的过程,但是,这却违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),我们把李四的作为人的行为和他工作的行为混在一起。

那我们再来看看接口(interface),引用航天奇侠兄的一句话,接口,就是一个类的函数规范。 一个类 “继承”一个接口,等于说这个类必须提供接口所要求的所有函数。但是呢他们是一种实现关系,虽然在C#里我们还叫它为继承接口,但实际它是一种"like a"的关系。

interface 工作
{
public void 上班();
}


class 张三 : 工作{}

interface 工作
{
public void 上班();
}


class 人 {}

class 李四 : 人,工作{}


interface 工作
{
public void 上班();
}

class 动物 {}

class 人 : 动物 {}

class 王五 : 人,工作{}

此时我们来看,张三和李四同样遵循着interface工作所定义的规范,但是呢,他们(类)的发展并不受到父类的影响,张三、李四、王五都可以自由的发展自身类,具备有很高的自由度,我们再来从面向对象设计角度看,李四、王五继承人(因为他本质就是人),实现了工作。
应该说,接口的使用面比抽象类更广一些,而抽象类呢比接口更具限制性,体现的是继承关系。
当类的发展不需要受到限制和约束时,我们可以使用接口,此类可以自由的发展,此时继承接口的这个类它就是一个稳定的类,这也体现了接口保持类的稳定性。


这两者具备有很大的相似性,都源直面向对象思想,在使用何时抽象类,何时接口并没有一个定论,应该根据自己程序的大小,设计的方式,程序发展的空间来看,这就需要大家自己斟酌了。
posted on 2007-05-21 14:40  KeithDan  阅读(3785)  评论(22编辑  收藏  举报