本帖最后由 陪你等日出 于 2014-3-1 14:23 编辑
以前我也有和楼主同样的困惑,觉得抽象类和接口区别不大,有时都可以用,后来看了很多讲解弄懂了。
首先,抽象类在java语言中表现的是一种继承关系,而且只能单继承,就意味着一个类只能使用一次继承关系,但是一个类却可以实现多个接口。然后,抽象类表示的是“is a”关系,接口表示的是“like a”关系。
那么决定使用接口还是使用抽象类就看你对问题领域的理解,你的设计意图是怎样的,举一个例子:
你要设计一个phone,这个phone中有两个功能:call,send,那么你可以这样设计
用抽象类定义:
- abstract class phone
- {
- abstract void call();
- abstract void send();
- }
复制代码
用接口定义:
- interface phone
- {
- void call();
- void send();
- }
复制代码
然后其它具体的phone对象可以通过继承抽象类phone,使用其中的方法,或者通过实现phone接口再使用其中的方法,这么看来区别不大,但是这时如果你想让这个手机不仅可以发送短信和打电话,还要拥有照相功能,那么你可以这样做:
抽象类中简单的加上拍照方法,让其成为拍照手机:
- abstract class phone
- {
- abstract void call();
- abstract void send();
- abstract void camera();
- }
复制代码
接口中简单的加上拍照方法,让其成为拍照手机:
- interface phone
- {
- void call();
- void send();
- void camera();
- }
复制代码
看起来是实现了功能要求,但是却违反了面向对象设计的一个核心原则ISP (Interface Segregation Principle),因为你将phone概念固有的功能和照相机的行为方法混在一起了。那么这里就是前面所说的,决定使用接口还是使用抽象类就看你对问题领域的理解,你的设计意图是怎样的,显然你要设计的是一个手机,那么就要这样设计:
- abstract class phone
- {
- abstract void call();
- abstract void send();
- }
- interface Camera
- {
- void camera();
- }
- //继承固有功能,实现照相功能
- class CameraPhone extends phone implements Camera
- {
- void call()
- {
- System.out.println("call phone");
- }
- void send()
- {
- System.out.println("send message");
- }
- void camera()
- {
- System.out.println("take photos");
- }
- }
复制代码
如果你想设计一个可以发送短信和打电话的照相机,那么你可以把上面的设计方式反过来,把camera()定义在抽象类里,把send()和call()定义在接口里。 |