原帖地址:http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
原作者:Rahman Mahmoodi
翻译:54sun
Introduction|介绍
我将通过这篇文章以及所附的demo程序讨论一下抽象类(Abstract class)和接口(Interface)。这两个概念往往会使面向对象语言的初学者感到迷惑,因此我尝试从理论上阐述它们的区别以及在使用的不同。最后我用C#语言来演示如何使用它们。
Background|背景
一个没有任何实现的抽象类看起来和接口没有区别!然而,抽象类和接口的区别要远比它们的共同点来得多。让我们共同看看它们的相似与区别吧。
What is an Abstract Class?|什么是抽象类?
抽象类就是一种无法被实例化(instantiated)的特殊的类。那么,我们需要这么一个无法生成对象的类呢?很简单,它的存在就是为了产生子类。换言之,它只能运行其他的类来继承它而它不会拥有自己的对象(也叫实例)。它的好处就是可以让你在实现父类子类这样的层次结构。简而言之,抽象类就好比一份合同,使得所有的子类都被强制实行同样的结构或者标准。
What is an Interface?|什么是接口?
接口不是类。它一个用关键词interface来定义的实体(译注,就好比用class来定义类)。一个接口没有实现,它只定义了函数(或叫方法,下同)声明而没有定义函数实现。它和抽象类的一个共同点就是:它也一份规范子类的合同(它声明的函数名,返回值和参数)。它们的主要不同在于:一个类可以实现多个接口但是只能继承一个父类。所以C#不像C++那样支持多重继承,而接口可以用来解决这个问题。
Both Together|两者一起
当我们声明了一个接口,相当于我们声明了一组函数--这些必须由某些类来实现它们。这样做的好处是它提供一种方式 ,使得一个类可以被分为两部分:一部分是通过继承得来的,另一部分是通过接口得来的。
当我们声明一个抽象类,相当于我们声明一个基础类--它可能已经提供了某些函数具体实现,不过至少必须有一个函数是没有定义实现的。它的目的就是定义的它的子类可以干什么,而至于如何干就留给了子类去实现。
我通过下面这个表来比较一下接口和抽象类之间的异同:
Feature|特性 | Interface|接口 | Abstract class|抽象类 |
Multiple inheritance 多重继承 | 一个类可以继承(实现)多个接口。 | 一个类只能继承一个父类。 |
Default implementation 默认实现 | 接口不能提供函数实现,只能提供函数定义。 | 抽象类可以提供完整的函数实现或者仅仅是在子类应该如何覆盖父类函数的信息。 |
Access Modfiers 访问修饰符 | 接口不能用访问控制符来修饰,函数和属性都不可以。所有的成员都被认为是public的。 | 抽象类可以对它的成员(函数、属性等)使用访问控制符来修饰。 |
Core VS Peripheral 核心 vs 周边 | 接口通常用来定义一个类的周边属性。换言之,人和车辆这两个类都可以实现‘可移动’这个接口。 | 抽象类定义一个类的核心属性也就是这个类的对象们的本质属性。 |
Homogeneity 同质性 | 如果各种函数实现只不过是有着同样的函数名,那么最好通过接口实现。 | 如果各种函数实现很类似,有着同样的行为,那么用抽象类就比较好。 |
Speed 速度 | 需要更多的时间来确定要调用的函数到底在哪个类中。(译注,应该是指通过接口对象来访问函数的情形) | 快 |
Adding functionality (Versioning) 扩展性(版本升级) | 如果我们添加一个新函数到接口里,我们必须检查所有实现的接口的类以保证每个使用了接口的类都实现了这个新添加的函数。 | 如果我们往抽象类里面添加一个新函数,并且提供一个默认的实现给此函数,那么此类的所有子类仍然可以正常工作。. |
Fields and Constants 变量域和常量 | 接口里面不能定义任何的变量和常量。 | 抽象类可以有变量域和常量这些数据成员存在。 |
Using the Code|代码
让我说明一下代码:我定义了一个抽象类Employee和一个
,在代码中我也用注释说明了它们的不同之处。我也通过生成它们的实例来对它们进行测试:我们继承抽象类Employee得到
Emp_Fulltime;实现
接口
IEmployee得到
Emp_Fulltime2。随后我们生成了这两子类的对象(实例)并对它们的属性进行赋值,再通过调用
calculateWage
来演示如何使用它们。
Abstract Class Employee
Interface Employee
Inherited Objects
Emp_Fulltime
:
Emp_Fulltime2
:
Code for Testing
Conclusion|结论
通过以上的例子,我说明了抽象类和接口之间的区别,并通过一个demo程序演示如何使用抽象类和接口。
License
这篇文章,以及所附的代码,都遵守:The Code Project Open License (CPOL)
……………………………………………………………………………………………………………………………………………………
为什么排版很好,显示却不一样呢。。。