java定义一个door的类_再探Java抽象类与接口的设计理念差异
原文:http://blog.csdn.net/sunboard/article/details/3831823 1.概述 一個軟件設計的好壞,我想很大程度上取決于它的整體架構,而這個整體架構其實就是你對整個宏觀商業業務的抽象框架,當代表業務邏輯的高層抽象層結構 合理時,你底層的具體實現需要考慮的
Java抽象類與接口都可以實現功能與實現的分離,都對多態提供了很好的支持,那么我們什么時候應該使用抽象類或接口呢?在以前的一篇文章初探Java抽象類與接口中談到了他們語法的區別,在博客通過模板方法模式深入理解Java抽象類中寫到了該如何正確使用抽象類,那么這次我就從更高的層次上——設計思想 上談談它們的差異!
1、抽象類與接口的抽象層次是不同的
抽象類是對類抽象,接口是對行為抽象。類包含了屬性與行為,所以說接口是更具體的抽象。
2、抽象類與接口的設計層次是不同的
抽象類是一種自下而上的設計,先有子類才能提取公同的屬性與行為,抽象出父類;
接口是一種自上而下的設計,先規定行為方法,只要可以實現這些行為,就可以成為接口的實現類。
3、抽象類與其派生類的關系和接口與其實現類的關系本質是不同的
抽象類與其派生類是一種“is-a”關系,即父類和派生子類在概念上的本質是相同的(父子關系,血緣聯系,很親密)。
接口與其實現類是一種“like-a”關系,即接口與實現類的關系只是實現了定義的行為,并無本質上的聯系(契約關系,很淡漠的利益關系)。
舉個例子:比如說一個動物抽象類,定義了跑的方法、叫的方法,但如果一個汽車類可以實現跑、可以實現叫,它就可以繼承動物抽象類嗎?!這太不合理了,汽車不是動物呀!而如果通過接口定義跑的方法、叫的方法,汽車類作為實現類實現跑和叫,完全OK很合理,就因為沒有繼承關系的約束。
為了更好的闡述他們之間的區別,下面將使用一個很棒的例子來說明。該例子引自博文鏈接。
我們有一個Door的抽象概念,它具備兩個行為open()和close(),此時我們可以定義通過抽象類和接口來定義這個抽象概念:
抽象類:
abstract class Door{
abstract void open();
abstract void close();
}
接口:
interface Door{
void open();
void close();
}
至于其他的派生類可以通過:
1、使用extends使用抽象類方式定義Door
2、使用implements接口方式定義Door出處:http://www.importnew.com/12399.html 首先明確,含有抽象方法的類就是抽象類,就必須用關鍵詞abstract聲明. 抽象類 抽象類是用來捕捉子類的通用特性的 。它不能被實例化,只能被用作子類的超類。抽象類是被用來創建繼承層級里子類的模板。 接口 接口是
這里發現兩者并沒有什么很大的差異,但是現在如果我們需要門具有報警的功能,那么該如何實現呢?
解決方案一:給Door增加一個報警方法:alarm();
abstract class Door{
abstract void open();
abstract void close();
abstract void alarm();
}
或者
interface Door{
void open();
void close();
void alarm();
}
這種方法違反了面向對象設計中的一個核心原則 ISP (Interface Segregation Principle)—見批注,在Door的定義中把Door概念本身固有的行為方法和另外一個概念”報警器”的行為方法混在了一起。這樣引起的一個問題是那些僅僅依賴于Door這個概念的模塊會因為”報警器”這個概念的改變而改變,反之依然。
解決方案二:
既然open()、close()和alarm()屬于兩個不同的概念,那么我們依據ISP原則將它們分開定義在兩個代表兩個不同概念的抽象類里面,定義的方式有三種:
1、兩個都使用抽象類來定義。
2、兩個都使用接口來定義。
3、一個使用抽象類定義,一個是用接口定義。
由于java不支持多繼承所以第一種是不可行的。后面兩種都是可行的,但是選擇何種就反映了你對問題域本質的理解。
如果選擇第二種都是接口來定義,那么就反映了兩個問題:
1、我們可能沒有理解清楚問題域,AlarmDoor在概念本質上到底是門還報警器。
2、如果我們對問題域的理解沒有問題,比如我們在分析時確定了AlarmDoor在本質上概念是一致的,那么我們在設計時就沒有正確的反映出我們的設計意圖。因為你使用了兩個接口來進行定義,他們概念的定義并不能夠反映上述含義。
第三種,如果我們對問題域的理解是這樣的:AlarmDoor本質上Door,但同時它也擁有報警的行為功能,這個時候我們使用第三種方案恰好可以闡述我們的設計意圖。AlarmDoor本質是們,所以對于這個概念我們使用抽象類來定義,同時AlarmDoor具備報警功能,說明它能夠完成報警概念中定義的行為功能,所以alarm可以使用接口來進行定義。如下:
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”關系,接口表示的是”like-a”關系,大家在選擇時可以作為一個依據,當然這是建立在對問題領域的理解上的,比如:如果我們認為AlarmDoor在概念本質上是報警器,同時又具有Door的功能,那么上述的定義方式就要反過來了。
批注: ISP(Interface Segregation Principle):面向對象的一個核心原則。它表明使用多個專門的接口比使用單一的總接口要好。
一個類對另外一個類的依賴性應當是建立在最小的接口上的。
一個接口代表一個角色,不應當將不同的角色都交給一個接口。沒有關系的接口合并在一起,形成一個臃腫的大接口,這是對角色和接口的污染。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的java定义一个door的类_再探Java抽象类与接口的设计理念差异的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 检测ie版本更新_[Java教
- 下一篇: php 反射类,PHP中的反射类