抽象类 和 接口 的区别
【转载+整理】http:/www.CrazyCoder.cn/Java/Article6560.html
1. 抽象类中的部分方法可以不实现,而接口则全部由派生类实现;
2. 抽象类是一个不完全的类,需要进一步专业化.接口只是一个行为的规范或规定, 基本上不具备继承的任何具体特点;
3. 一个类一次可以实现若干个接口,但是只能扩展一个父类;
4. 在abstract class的定义中,我们可以赋予方法的默认行为;
5. 抽象类一般作为公共的父类为子类的扩展提供基础,这里的扩展包括了属性上和行为上的。
而接口一般来说不考虑属性,只考虑方法,使得子类可以自由的填补或者扩展接口所定义的方法
6. 接口可以用于支持回调,而继承并不具备这个特点;
7. 抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能;
8. 如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类;
从语义来看---
抽象类和接口都是 对 问题域 的“抽象”, 不能被实例化的。
为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。
从语法来看---
抽象类可以有自己的数据成员,也可以有非abstarct的成员方法,可以有默认行为。
而在interface中只能够有静态的 不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。
从某种意义上说,interface是一种特殊 形式的abstract class。
从设计层面看---
抽象类体现继承关系(is a):抽象类主要描述类型的类属关系,抽象类和它的派生类之间是典型的IS-A关系。
interface(can do),并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已;接口主要描述的是类型间的行为合同,接口和它的实现类之间是典型的CAN-DO关系。
实例:
abstract class Door {
abstract void open();
abstract void close();
}
使用interface方式定义Door:
interface Door {
void open();
void close();
}
其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。
看起来好像使用abstract class和interface没有大的区别
如果现在要求Door还要具有报警的功能?
解决方案一
简单的在Door的定义中增加一个alarm方法
abstract class Door {
abstract void open();
abstract void close();
abstract void alarm();
}
或者
interface Door {
void open();
void close();
void alarm();
}
这种方法违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。
解决方案二
既然open/close和alarm属于两个不同的概念,根据ISP原则,
a. 这两个概念都使用abstract class方式定义;
b. 两个概念都使用interface方式定义;
c. 一个概念使用abstract class方式定义,另一个概念使用interface方式定义。
C#不支持多重继承,第一种不行;
第二种,我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?
我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同 时它有具有报警的功能。
abstract class Door {
abstract void open();
abstract void close();
}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}
这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计 意图
出处:http://www.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。