在JAVA语言中, abstract class 和 interface 都是用来支持抽象的。两者对类型抽象有很类似的一面,并且大部分地方甚至可以互换,所以在使用的时候可能比较随意。下面从纯粹语义,编程实践和设计三方面进行分析二者的不同之处。
1.语义来讲。
interface :能够完成特定功能的,由若干属性和方法组织成的,相对独立的属性和方法的集合。
abstract class:抽象类是不允许实例化的类
在语法层面,Java语言中,abstract class和interface定义方式各异。abstract class可以有自己的数据成员,也可以有非 abstract的成员方法,而interface只能够有静态的不能被修改的数据成员(static final),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的 abstract class。
abstract class 和 interface 其实是用来一起实现c++的多重继承,同时避开多重继承的各种复杂和弊端(如对于不同父类相同函数二义性的问题)。
2.从编程的角度来看。
首先,abstract class 在 Java 中表示继承关系,一个类有只能继承一个父类。但是,一个类却可以实现多个interface。
其次,abstract class的定义中,可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。
在 interface中不能定义默认行为,可能会造成维护上的麻烦。若后来想修改类的一些方法以适应新的情况(比如,添加新的方法或者给已用的方法中添 加新的参数)时,可能要花费很多的时间,因为要分别去实现。但是若方法是通过abstract class来实现的,那 么就只需要修改定义在abstract class中的默认行为就可以了。
同样,如果不能在抽象类中抽象出默认行为,就会导致该抽象类的每一个派生类中实现该方法,违反了 "one rule,one place" 原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。
3.从设计角度
abstract class在Java中体现的是一种继承关系,父类和派生类之间必须存在"is-a"关系,即父类和派生类在概念本质上应该是相同的,子类能用在所有父类可以用的地方。而interface则是“like-a”关系,不要求interface的实现者和interface定义在概念本质上是一致的, 仅仅是实现了interface定义的契约而已。
1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
5 .接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
7.接口中的方法默认都是 public,abstract 类型的。
在实际编程中,一般能用interface的地方则用interface, 除非该抽象类有默认行为。主要是考虑到java中,是单继承的,若使用了抽象类,则限制了其继承其他类,很多控件,框架可能要求继承其抽象类,由.abstract class 修改为 interface,比较麻烦。使用interface,则可以很容易的新增加一个抽象类。