Java中的接口和抽象类区别
在Java面向对象编程中,总会用到接口和抽象类,他们都是对事物的一种抽象,有一些共同点但是也有很多区别。
接口Interface
在Java中接口需要用interface关键字定义,他是对一种行为的抽象,是一种约定的协议,只定义行为不会实现具体的行为(Java 1.8中有default 方法)。
Java中定义一个接口:
public interface InterfaceName{
public void doSomething();
}
在接口中的行为必须都是公共的,如果定义成员变量也必须是静态不可变的(static final)。接口中定义的行为都是abstract的,也可以理解为特殊的抽象。
抽象类abstract class
在面向对象的编程中,对象都是通过class来描述的,,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类需要用abstract关键字来定义,表示一个类为抽象类,抽象类是对一类事物共性的一种抽象,实现公共的行为,并且构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。
抽象类中用abstract表示就是个抽象类,一般都有抽象方法,如果定义没有抽象方法的抽象类,在语法层面是可行的,但是实际并很少这么用。
Java中抽象类的定义:
public abstract class{
public void doSomething(){
//do some thing
}
public/protected void doAnything();
}
从语法定义层面看abstract class和interface
在abstract class方式中,可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,只能够有静态的不能被修改的数据成员,所有的成员方法都是abstract的并且为公有的。
具体区别如下:
抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法(Java 1.8中有default 方法);
抽象类中的成员变量可以是private、protected和public,而接口中的成员变量只能是public static final类型的;
接口中不能含有静态方法和代码块,而抽象类可以有静态代码块和静态方法;
一个类只能继承一个抽象类,而一个类却可以实现多个接口。如果一个类实现部分接口的方法这个类也需要定义为抽象类。
从设计区分abstract class和interface
abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。
可以理解为抽象类是对一类事物的抽象,而接口是对行为的抽象。
下面引用一个很经典的例子,大神们分析好了,我们看一看。
假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:
使用abstract class方式定义Door:
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()。这种方法首先违反了面向对象设计中的一个单一原则,在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。如果一个门根本没有报警器功能,也得跟着修改。
另一种就是增加单独报警接口,由于Java语言不支持多重继承,所以应该把报警设计成接口。Abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系,把Door设计成抽象类比较合适,报警只是一种行为从设计上说也应该设计成接口。
所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:
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() { … }
}
领取专属 10元无门槛券
私享最新 技术干货