Java中的接口和抽象类区别

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() { … }

}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200415A0FKJA00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券