大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 詳解抽象類與接口區(qū)別

詳解抽象類與接口區(qū)別

更新時(shí)間:2020-10-16 17:28:12 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1475次

盡管抽象類和接口之間存在較大的相同點(diǎn),甚至有時(shí)候還可以互換,但這并不能彌補(bǔ)他們之間的差異之處。下面將從語法層次和設(shè)計(jì)層次兩個(gè)大的方面對(duì)抽象類與接口區(qū)別進(jìn)行闡述。


一、語法層次

在語法層次,java語言對(duì)于抽象類和接口分別給出了不同的定義。下面已Demo類來說明他們之間的不同之處。

使用抽象類來實(shí)現(xiàn):

public abstract class Demo {

abstract void method1();

void method2(){

//實(shí)現(xiàn)

}

}

使用接口來實(shí)現(xiàn)

interface Demo {

void method1();

void method2();

}

抽象類方式中,抽象類可以擁有任意范圍的成員數(shù)據(jù),同時(shí)也可以擁有自己的非抽象方法,但是接口方式中,它僅能夠有靜態(tài)、不能修改的成員數(shù)據(jù)(但是我們一般是不會(huì)在接口中使用成員數(shù)據(jù)),同時(shí)它所有的方法都必須是抽象的。在某種程度上來說,接口是抽象類的特殊化。

對(duì)子類而言,它只能繼承一個(gè)抽象類(這是java為了數(shù)據(jù)安全而考慮的),但是卻可以實(shí)現(xiàn)多個(gè)接口。


二、設(shè)計(jì)層次

上面只是從語法層次和編程角度來區(qū)分它們之間的關(guān)系,這些都是低層次的,要真正使用好抽象類和接口,我們就必須要從較高層次來區(qū)分了。只有從設(shè)計(jì)理念的角度才能看出它們的本質(zhì)所在。一般來說他們存在如下三個(gè)不同點(diǎn):


1、 抽象層次不同。抽象類是對(duì)類抽象,而接口是對(duì)行為的抽象。抽象類是對(duì)整個(gè)類整體進(jìn)行抽象,包括屬性、行為,但是接口卻是對(duì)類局部(行為)進(jìn)行抽象。

2、 跨域不同。抽象類所跨域的是具有相似特點(diǎn)的類,而接口卻可以跨域不同的類。我們知道抽象類是從子類中發(fā)現(xiàn)公共部分,然后泛化成抽象類,子類繼承該父類即可,但是接口不同。實(shí)現(xiàn)它的子類可以不存在任何關(guān)系,共同之處。例如貓、狗可以抽象成一個(gè)動(dòng)物類抽象類,具備叫的方法。鳥、飛機(jī)可以實(shí)現(xiàn)飛Fly接口,具備飛的行為,這里我們總不能將鳥、飛機(jī)共用一個(gè)父類吧!所以說抽象類所體現(xiàn)的是一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is-a" 關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對(duì)于接口則不然,并不要求接口的實(shí)現(xiàn)者和接口定義在概念本質(zhì)上是一致的, 僅僅是實(shí)現(xiàn)了接口定義的契約而已。

3、 設(shè)計(jì)層次不同。對(duì)于抽象類而言,它是自下而上來設(shè)計(jì)的,我們要先知道子類才能抽象出父類,而接口則不同,它根本就不需要知道子類的存在,只需要定義一個(gè)規(guī)則即可,至于什么子類、什么時(shí)候怎么實(shí)現(xiàn)它一概不知。比如我們只有一個(gè)貓類在這里,如果你這是就抽象成一個(gè)動(dòng)物類,是不是設(shè)計(jì)有點(diǎn)兒過度?我們起碼要有兩個(gè)動(dòng)物類,貓、狗在這里,我們?cè)诔橄笏麄兊墓餐c(diǎn)形成動(dòng)物抽象類吧!所以說抽象類往往都是通過重構(gòu)而來的!但是接口就不同,比如說飛,我們根本就不知道會(huì)有什么東西來實(shí)現(xiàn)這個(gè)飛接口,怎么實(shí)現(xiàn)也不得而知,我們要做的就是事前定義好飛的行為接口。所以說抽象類是自底向上抽象而來的,接口是自頂向下設(shè)計(jì)出來的。

為了更好的闡述他們之間的區(qū)別,我們將用實(shí)例來說明:


我們有一個(gè)Door的抽象概念,它具備兩個(gè)行為open()和close(),此時(shí)我們可以定義通過抽象類和接口來定義這個(gè)抽象概念:

抽象類:

abstract class Door{

abstract void open();

abstract void close();

}

接口

interface Door{

void open();

void close();

}

至于其他的具體類可以通過使用extends使用抽象類方式定義Door或者Implements使用接口方式定義Door,這里發(fā)現(xiàn)兩者并沒有什么很大的差異。

但是現(xiàn)在如果我們需要門具有報(bào)警的功能,那么該如何實(shí)現(xiàn)呢?


解決方案一:給Door增加一個(gè)報(bào)警方法:clarm();

abstract class Door{

abstract void open();

abstract void close();

abstract void alarm();

}

或者

interface Door{

void open();

void close();

void alarm();

}

這種方法違反了面向?qū)ο笤O(shè)計(jì)中的一個(gè)核心原則 ISP (Interface Segregation Principle)—見批注,在Door的定義中把Door概念本身固有的行為方法和另外一個(gè)概念"報(bào)警器"的行為方 法混在了一起。這樣引起的一個(gè)問題是那些僅僅依賴于Door這個(gè)概念的模塊會(huì)因?yàn)?quot;報(bào)警器"這個(gè)概念的改變而改變,反之依然。


解決方案二

既然open()、close()和alarm()屬于兩個(gè)不同的概念,那么我們依據(jù)ISP原則將它們分開定義在兩個(gè)代表兩個(gè)不同概念的抽象類里面,定義的方式有三種:

1、兩個(gè)都使用抽象類來定義。

2、兩個(gè)都使用接口來定義。

3、一個(gè)使用抽象類定義,一個(gè)是用接口定義。

由于java不支持多繼承所以第一種是不可行的。后面兩種都是可行的,但是選擇何種就反映了你對(duì)問題域本質(zhì)的理解。

如果選擇第二種都是接口來定義,那么就反映了兩個(gè)問題:1、我們可能沒有理解清楚問題域,AlarmDoor在概念本質(zhì)上到底是門還報(bào)警器。2、如果我們對(duì)問題域的理解沒有問題,比如我們?cè)诜治鰰r(shí)確定了AlarmDoor在本質(zhì)上概念是一致的,那么我們?cè)谠O(shè)計(jì)時(shí)就沒有正確的反映出我們的設(shè)計(jì)意圖。因?yàn)槟闶褂昧藘蓚€(gè)接口來進(jìn)行定義,他們概念的定義并不能夠反映上述含義。


第三種,如果我們對(duì)問題域的理解是這樣的:AlarmDoor本質(zhì)上Door,但同時(shí)它也擁有報(bào)警的行為功能,這個(gè)時(shí)候我們使用第三種方案恰好可以闡述我們的設(shè)計(jì)意圖。AlarmDoor本質(zhì)是們,所以對(duì)于這個(gè)概念我們使用抽象類來定義,同時(shí)AlarmDoor具備報(bào)警功能,說明它能夠完成報(bào)警概念中定義的行為功能,所以alarm可以使用接口來進(jìn)行定義。如下:

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

}


這種實(shí)現(xiàn)方式基本上能夠明確的反映出我們對(duì)于問題領(lǐng)域的理解,正確的揭示我們的設(shè)計(jì)意圖。其實(shí)抽象類表示的是"is-a"關(guān)系,接口表示的是"like-a"關(guān)系,大家在選擇時(shí)可以作為一個(gè)依據(jù),當(dāng)然這是建立在對(duì)問題領(lǐng)域的理解上的,比如:如果我們認(rèn)為AlarmDoor在概念本質(zhì)上是報(bào)警器,同時(shí)又具有Door的功能,那么上述的定義方式就要反過來了。

一個(gè)類對(duì)另外一個(gè)類的依賴性應(yīng)當(dāng)是建立在最小的接口上的。

一個(gè)接口代表一個(gè)角色,不應(yīng)當(dāng)將不同的角色都交給一個(gè)接口。沒有關(guān)系的接口合并在一起,形成一個(gè)臃腫的大接口,這是對(duì)角色和接口的污染。


通過實(shí)例,我們發(fā)現(xiàn)其實(shí)接口和抽象類區(qū)別還是蠻大的,不論是在語法層次,還是在設(shè)計(jì)層次都有著嚴(yán)格的區(qū)分。從構(gòu)造方法到普通成員變量,這些都是區(qū)分接口和抽象類的典型標(biāo)志。接口更多的是在系統(tǒng)架構(gòu)設(shè)計(jì)方法發(fā)揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實(shí)現(xiàn)方面發(fā)揮作用,可以實(shí)現(xiàn)代碼的重用。本文對(duì)接口和抽象類區(qū)別的講解是不是很透徹呢?這些Java基礎(chǔ)知識(shí)在本站的Java零基礎(chǔ)入門教程中還有更加精彩的講解,想深入學(xué)習(xí)Java的小伙伴不容錯(cuò)過哦。


提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 国产成人丝袜精品自啪在线 | 欧美做爰xxxⅹ在线视频hd | 日本免费高清一区 | 一区二区三区在线视频观看 | 国产真实强j视频在线观看 国产真实偷乱视频在线观看 | 天天操天天擦 | 一级国产20岁美女毛片 | 色狠狠狠色噜噜噜综合网 | 欧美激情在线免费观看 | jiucao视频在线观看 | 狠狠操天天操夜夜操 | 奇米影视888狠狠狠777九色 | 国产高清免费午夜在线视频 | 久久99精品久久久久久噜噜 | 99re久久资源最新地址 | 大色佬视频在线观看 | 亚洲天天在线日亚洲洲精 | 中文字幕 二区 三区 搜查官 | 欧美成人 一区二区三区 | 亚洲视频1| 精品无码久久久久国产 | 国产成人精品aaaa视频一区 | 国产99久久亚洲综合精品 | 日韩免费一级毛片 | 99精品国产久热在线观看66 | 九九九影院 | 久久频这里精品香蕉久久 | 中文字幕在线观看一区 | 日日爽天天干 | 中文字幕人成不卡一区 | 黄色毛片视频网站 | 99尹人香蕉国产免费天天拍 | 天天干夜夜爽天天操夜夜爽视频 | 日本在线不卡免费 | 在线播放精品一区二区啪视频 | 天天射综合网站 | 91视频官网 | 亚洲四房 | 亚久久| 国产午夜精品一区二区三区嫩草 | 五月天婷婷久久 |