详细解析Java中抽象类和接口的区别

Java言中, abstract class interface 是支持抽象的两机制。正是由于机制的存在,才予了Java大的 面向象能力。abstract classinterface于抽象的支持方面具有很大的相似性,甚至可以相互替,因此很多开发者在行抽象义时对abstract classinterface选择显得比随意。,两者之间还是有很大的区的,于它选择甚至反映出 问题领域本的理解、设计的理解是否正确、合理。本文将的区别进行一番剖析,试图给开发者提供一个在二者之间进选择的依据。


理解抽象
abstract class
interfaceJava言中都是用来行抽象(本文 中的抽象并非从abstract class而来,它表示的是一个抽象体,而abstract classJava言中用于定抽象的一方法, 请读者注意区分)定的,那是抽象,使用抽象们带来什呢?

在面向象的概念中,我知道所有的象都是通过类来描的,但是反来却不是这样。并不是所有的都是用来描绘对象的,如果一个中没有包含足的信息来描一个具体的这样就是抽象抽象往往用来表征我对问题领行分析、 设计中得出的抽象概念,是一系列看上去不同,但是本上相同的具体概念的抽象。比如:如果我们进行一个编辑软件的开发,就会发现问题领域存在着 三角形这样一些具体概念,它是不同的,但是它又都属于形状这样一个概念,形状个概念在问题领域是不存在的,它就是一个抽象概念。正是因抽象的概念 问题领域没有对应的具体概念,所以用以表征抽象概念的抽象是不能够实例化的。

在面向域,抽象主要用来藏。 可以构造出一个固定的一的抽象描述,但是这组却能有任意个可能的具体实现方式。个抽象描述就是抽象,而任意个可能的具体实现则现为所有可能的派生。模可以操作一个抽象体。由于模于一个固定的抽象体,因此它可以是不允修改的;同,通个抽象体派生,也可展此模的行功能。熟悉OCP者一定知道,了能够实现面向设计的一个最核心的原OCP(Open-Closed Principle),抽象是其中的关键所在。

法定义层面看abstract class interface
面,Javaabstract classinterface出了不同的定方式,下面以定一个名Demo的抽象类为例来这种不同。

使用abstract class的方式定Demo抽象的方式如下:

abstract class Demo
     abstract void method1();
     abstract void method2();
     …

使用interface的方式定Demo抽象的方式如下:

interface Demo{
     void method1();
     void method2();
     …
}

abstract class方式中,Demo可以有自己的数据成,也可以有非 abstract的成方法,而在interface方式的实现中,Demo只能有静的不能被修改的数据成(也就是必static final 的,不interface中一般不定数据成),所有的成方法都是abstract的。从某interface是一特殊形式的 abstract class

程的角度来看,abstract classinterface都可以用来实现 "design by contract" 的思想。但是在具体的使用上面是有一些区的。

首先,abstract class Java 言中表示的是一种继系,一个只能使用一次(Java不支持多 -- )。但是,一个却可以实现多个interface。也Java言的设计者在考Java于多重承的支持方面的一折中考吧。

其次,在abstract class的定中,我可以予方法的默。但是在interface的定中,方法却不能有默绕过这个限制,必使用委托,但是会增加一些复杂性,有会造成很大的麻

Interface中不能定为还存在另一个比较严重的问题,那就是可能会造成维护上的麻。因如果后来想修改的界面(一般通abstract class或者interface来表示)以适新的情况(比如,添加新的方法或者已用的方法中添加新的参数),就会非常的麻,可能要花很多的时间于派生很多的情况,尤如此)。但是如果界面是通abstract class实现的,那可能就只需要修改定abstract class中的默就可以了。

,如果不能在抽象中定,就会致同的方法实现抽象一个派生中,反了 "one ruleone place" ,造成代,同不利于以后的维护。因此,在abstract classinterface间进选择时要非常的小心。

设计理念面看 abstract class interface
上面主要从法定程的角度述了abstract classinterface的区面的区是比次的、非本的。本小将从另一个面:abstract classinterface所反映出的设计理念,来分析一下二 者的区。作者认为,从行分析才能理解二者概念的本所在。

前面已提到abstract classJava言中体了一种继系,要想使得系合理,父和派生存在"is-a"系,即父和派生在概念本应该是相同的(参考文献〔3〕中有"is-a"系的大篇幅深入的述,有趣的者可以参考)。interface说则不然,并不要求interface实现者和interface在概念本上是一致的, 仅仅实现interface的契而已。了使述便于理解,下面将通一个简单明。

虑这样一个例子,假在我问题领域中有一个Door的抽象概念,Door具有行两个openclose,此可以通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 classinterface没有大的区

如果在要求Door要具有警的功能。我们该如何设计针对该例子的类结构呢(在本例中, 主要是了展示 abstract class interface 反映在设计理念上的区,其他方面无问题都做了化或者忽略)?下面将列出可能的解决方案,并从设计理念对这些不同的方案行分析。

解决方案一:

简单的在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(){…}

这种方法反了面向设计中的一个核心原 ISP (Interface Segregation Principle),在Door的定中把Door概念本身固有的行方法和另外一个概念"警器"的行方法混在了一起。这样引起的一个问题是那些仅仅Door个概念的模会因"警器"个概念的改(比如:追加了alarm方法)而改,反之依然。

解决方案二:

既然openclosealarm属于两个不同的概念,根据ISP则应该把它在代表两个概念的抽象中。定方式有:两个概念都使用 abstract class 方式定;两个概念都使用interface方式定;一个概念使用 abstract class 方式定,另一个概念使用interface方式定

然,由于Java言不支持多重承,所以两个概念都使用abstract class方式定是不可行的。后面两方式都是可行的,但是于它选择却反映出问题领域中的概念本的理解、设计的反映是否正确、合理。我一一来分析、明。

如果两个概念都使用interface方式来定,那就反映出两个问题1、我可能没有 理解清楚问题领域,AlarmDoor在概念本上到底是Door警器?2、如果我们对问题领域的理解没有问题,比如:我过对问题领域的分析发现AlarmDoor在概念本上和Door是一致的,那实现时就没有能正确的示我设计,因两个概念的定上(均使用 interface方式定)反映不出上述含

如果我们对问题领域的理解是:AlarmDoor在概念本上是Door,同它有具有 警的功能。们该如何来设计实现来明确的反映出我的意思呢?前面已经说过abstract classJava言中表示一种继系,而 在本上是"is-a"系。所以Door个概念,我们应该使用abstarct class方式来定另外,AlarmDoor又具有警功能,明它又能完成警概念中定的行,所以警概念可以通interface方式定如下所示:

abstract class Door{
     abstract void open();
     abstract void close()

}
interface Alarm{
     void alarm();
}
class Alarm Door extends Door implements Alarm{
     void open(){…}
     void close(){…}
     void alarm(){…}
}

这种实现方式基本上能明确的反映出我们对问题领域的理解,正确的示我设计。其abstract class表示的是"is-a"系,interface表示的是"like-a"系,大家在选择时可以作一个依据,当然是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本上是警器,同又具有Door的功能,那上述的定方式就要反来了,将Alarm定义为abstract classDoor定义为接口


1.abstract class
Java 言中表示的是一种继系,一个只能使用一次系。但是,一个却可以实现多个interface
2.abstract class 中可以有自己的数据成,也可以有非abstarct的成方法,而在interface中,只能有静的不能被修改的数据成(也就是必static final的,不 interface中一般不定数据成),所有的成方法都是abstract的。
3.abstract classinterface所反映出的设计理念不同。其abstract class表示的是"is-a"系,interface表示的是"like-a"系。
4.
实现抽象和接口的须实现其中的所有方法。抽象中可以有非抽象方法。接口中不能有实现方法。

5.
接口中定量默public static final 型,且必须给其初,所以实现类中不能重新定,也不能改
6.
抽象中的量默 friendly 型,其可以在子中重新定,也可以重新赋值
7.
接口中的方法默都是 public,abstract 型的。

结论

abstract class interface Java言中的两抽象的方式,它有很大的相似性。但是于它选择却又往往反映出问题领域中的概念本的理解、设计的反映是否正确、合理,因了概念的不同的系(然都能够实现需求的功能)。也是言的一用法,希望者朋友能够细细体会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值