【转】Java的接口和抽象类的区别

1.      抽象类和接口的区别

所谓抽象类是用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象;所谓接口,相当于电源插座,可插入构件相当于电器。可插入构件的关键在于存在一个公用的接口,以及每个构件都实现了这个接口。接口是实现构件的可插入性的关键。

1.1.   从语法层区别抽象类和接口

从语法层来讲,Java语言对于抽象类和接口给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。

Demo抽象类的定义方式如下:

abstract class Demo {

abstract void method1();

abstract void method2();

}

Demo的接口定义方式如下:

interface Demo {

void method1();

void method2();

}

在抽象类的定义中,Demo可以有自己的数据成员,也可以有非abstract的成员方法,而在接口的定义中,Demo只能够有static final数据成员,所有的成员方法都是abstract的。从某种意义上说,接口是一种特殊形式的抽象类。

从编程的角度来看,首先,抽象类和接口的继承规则不同,抽象只允许单继承,而一个类却可以实现多个接口。接口对于多重继承的支持方面的一种折中考虑;其次,在抽象类的定义中,可以赋予方法的默认行为,而在接口的定义中,方法不能拥有默认行为,必须使用委托,从某种意义上来说,接口比抽象类更为抽象化。

1.2.   从设计层上理解抽象类和接口

上面主要从语法层的角度论述了抽象类和接口的区别,这些层面的区别是比较低层次的、非本质的。本小节将从这个设计层进行分析理解二者概念的本质。

抽象类在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"Is-A"关系,即父类和子类在概念本质上应该是相同的。对于接口来说则不然,接口并不要求实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已。考虑这样一个例子,假设在有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过抽象类或者接口来定义一个表示该抽象概念的类型,定义方式分别如下所示:

Door抽象类的定义方式如下:

abstract class Door {

abstract void open();

abstract void close();

}

Door的接口定义方式如下:

interface Door {

void open();

void close();

}

其他具体的Door类型可以extends使用抽象类方式定义的Door或者implements使用接口方式定义的Door。看起来好像使用抽象类和接口没有大的区别。如果现在要求Door还要具有报警的功能。下面将罗列出可能的解决方案,并从设计层对方案进行分析。

解决方案一:

简单的在Door的定义中增加一个alarm方法,如下:

abstract class Door {

abstract void open();

abstract void close();

abstract void alarm();

}

或者

interface Door {

void open();

void close();

void alarm();

}

那么具有报警功能的AlarmDoor的定义方式如下:

class AlarmDoor extends Door {

void open(){…}

void close(){…}

void alarm(){…}

}

或者

class AlarmDoor implements Door{

void open(){…}

void close(){…}

void alarm(){…}

}

这种方法违反了接口隔离原则,在Door的定义中把Door概念本身固有的行为方法和另外一个概念“报警器”的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为“报警器”这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。

解决方案二:

既然open、close和alarm属于两个不同的概念,根据接口隔离原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用抽象类方式定义;两个概念都使用接口方式定义;一个概念使用抽象类方式定义,另一个概念使用接口方式定义。

显然,由于Java语言不支持多重继承,所以两个概念都使用抽象类方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。

如果两个概念都使用接口方式来定义,那么就反映出两个问题:第一,我们可能没有理解清楚问题领域,AlarmDoor在概念本质上 到底是Door还是报警器?第二,如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用接口方式定义)反映不出上述含义。

如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,抽象类在Java语言中表示一种继承关系,而继承关系在本质上是"Is-A"关系。所以对于Door这个概念,我们应该使用抽象类方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过接口方式定义。如下所示:

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

}

这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实抽象类表示的是"Is-A"关系,interface表示的是"Has-A"关系,在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有 Door的功能,那么上述的定义方式就要反过来了。

2.      抽象机制的重要性

抽象机制是面向对象的可复用设计的必要条件。

面向对象的可复用设计的基石是开闭原则,也即一个软件实体应该对扩展开放,对修改关闭。满足开闭原则的关键就在于抽象化。在Java这样的面向对象的编程语言里,可以给系统定义出一个一劳永逸,不在更改的抽象设计,此设计允许有无穷无尽的行为在实现层被实现。在Java语言里,可以给出一个或者多个抽象类或接口,规定出所有的可能的扩展,因此在任何扩展的情况下都不会改变。这就使得系统的抽象层不需修改,从而满足了开闭原则的第二条:对修改关闭。同时,由于从抽象层导出一个或者多个新的具体类可以改变系统的行为,因此系统对扩展是开放的,这就满足了开闭原则的第一条:对扩展开放。

所有的软件系统都有一个共同的性质,即对它们的需求都会随时间的推移而发生变化,在软件系统面临新的需求时,系统的设计必须是稳定的。满足开闭原则的设计可以给软件系统带来一定适应性和灵活性,使变化中的软件系统具有一定的稳定性和延续性。

3.      结论

抽象类和接口是Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系。只有正确理解面向对象的设计原则并灵活使用抽象类和接口,才能设计出易用的系统

时间: 2024-07-29 08:11:38

【转】Java的接口和抽象类的区别的相关文章

Java中接口和抽象类的区别与联系

Java中接口和抽象类的区别与联系 1. 抽象类: (1).概念:抽象类是对一种事物的抽象,即对类抽..抽象类是对整个类整体进行抽象,包括属性.行为.Java抽象类和Java接口一样,都用来声明一个新的类型.并且作为一个类型的等级结构的起点. (2).格式: public abstract class abstractDemo{ /**属性*/ private String name; /**方法*/ public abstract void fun(); } (3).说明: A:抽象类中不一定

Java中接口和抽象类的区别?

抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public 或 procted,如果定义为 private,那么子类则无法继承.抽象类不能创建对象 抽象类和普通类的区别 抽象类必须用public.procted 修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法).默认缺省为 public 抽象类无法创建对象 如果一个子类继承抽象类

java中接口与抽象类的区别

接口和抽象类的共同特征如下: 接口和抽象类都不能被实例化,位于继承树的顶端,用于被其他类实现和继承. 接口和抽象类都可以包含抽象的方法,实现接口的类或者继承抽象类的类都必须实现这些抽象的方法. 区别:二者的主要区别在于他们存在的目的不同,即设计的目的不同. 接口作为系统与外界交互的窗口,接口体现的是一种规范. 抽象类作为系统中多个子类的共同父类,抽象类体现的是一种模板式设计. 我们最关注的还是二者用法的区别: (1)接口里只能包含抽象方法和默认方法,不能实现普通方法.抽象类完全可以包含普通方法.

java中接口和抽象类的区别

抽象类: 1.用abstract表示 2.里面有一个或多个抽象方法,在方法前加abstract,抽象类中也可以没有抽象方法 3.抽象类用extends继承,并且必须重写抽象方法 接口 1.用implement表示 2.接口是极度抽象的类,所有方法都是抽象的,都需要进行重写 接口的作用:解决java中的单继承问题,一个类可以实现多个接口,但只能有一个父类 共同点:都不能被实例化

2.35 Java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别

java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别 一.抽象 abstract作用:不能产生对象,充当父类,强制子类正确实现重写方法和类相比仅有的改变是不能产生对象,其他的都有,包括构造.属性等等任何一个类只要有一个抽象的方法就成了抽象类 抽象方法 public abstract A();①方法是抽象的,这个类也是抽象的:②子类必须重写抽象方法,除非子类也是抽象类 抽象类可以没有抽象方法,但一般不这么设计 二.接口 interface 接口也是Java的一种引用数据类型(J

Java知多少(40)接口和抽象类的区别

类是对象的模板,抽象类和接口可以看做是具体的类的模板. 由于从某种角度讲,接口是一种特殊的抽象类,它们的渊源颇深,有很大的相似之处,所以在选择使用谁的问题上很容易迷糊.我们首先分析它们具有的相同点. 都代表类树形结构的抽象层.在使用引用变量时,尽量使用类结构的抽象层,使方法的定义和实现分离,这样做对于代码有松散耦合的好处. 都不能被实例化. 都能包含抽象方法.抽象方法用来描述系统提供哪些功能,而不必关心具体的实现. 下面说一下抽象类和接口的主要区别. 1) 抽象类可以为部分方法提供实现,避免了在

java的接口和抽象类区别

转自:深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一.抽象类 二.接口 三.抽象类和接口的区别 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式

java 接口和抽象类的区别

接口和抽象类的区别:1,接口里不能定义私有的方法/变量,抽象类可以但抽象类如果定义了私有变量,一般会定义一个共有方法来使用这个变量不然这个变量就没有意义了private String name:public void setName(String name){ this.name = name;}public String getName(){ return name;}2,接口里定义的方法没有方法体(除非定义为public/default) 抽象类定义的方法有方法体3,接口定义的方法需要全部被

《java基础知识》Java接口和抽象类的区别

抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public 或 procted,如果定义为 private,那么子类则无法继承.抽象类不能创建对象 抽象类和普通类的区别 抽象类必须用public.procted 修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法).默认缺省为 public 抽象类无法创建对象 如果一个子类继承抽象类