抽象類?這個東西我感受沒什麼卵用啊,又不能拿來new對象,沒有具體的對象的抽象類,有什麼實際的意義呢?這是不少剛剛接觸java抽象類語法時的第一反應(固然,包括我)。確實,不少剛剛接觸抽象類這個概念的程序員都沒法真正理解抽象類存在的意義,感受java中的這個專門只能拿來繼承並實現了對應抽象方法才能真正有那麼一點用處的父類確實有點多餘。java
確實,若是你只是一個應用開發者(固然,是指簡單地實現業務功能),或許你永遠也不用抽象類,由於,它原本就不是拿來當具體的應用功能開發用的類,它是用來實現傳說中的架構建模用的,沒錯,就是這個簡答的抽象類,是架構師構建大型架構必不可少的工具,廢話很少說,下面咱們一塊兒感覺抽象類在架構設計中的威力(固然,真正的 威力確定比我描述的強大得多,畢竟,目前我對抽象類的架構建模思想也是懂點皮毛,或許皮毛都不算)程序員
1、具體類實現功能web
在討論抽象類前,咱們先簡單地討論具體類的一些例子,以便和抽象類進行對比,好了,首先看一個很稀鬆例子:編程
//一個簡單的汽車類 class Car{ //該類有如下方法 //點火方法 public void fire(){ System.out.println("我是汽車,給我點火,個人發動機會開始轉動"); } //駕駛方法 public void run(){ System.out.println("我是車,我如今在駕駛,注意,我和倒車不一樣,我是向前走"); } //倒車方法 public void backCar(){ System.out.println("我是車,我如今在倒車,注意,我和駕駛不一樣,我是向後走"); } //如今有一個動做:放置好車輛(好吧,這個說法有點牽強,只是爲了說明例子,別太在乎) public void setCar(){ //首先,你要對車點火才能驅動車行駛,才能將車放到車庫(原諒我這裏的不面向對象,一切只爲說明問題實質) fire(); //恩,向前走,去到車庫 run(); //ok,我要倒車入庫了 backCar(); //...固然,後續其餘操做:熄火啊什麼的 } }
好吧,代碼有點長,可能你如今一臉懵逼不知道我爲毛舉一個這麼腦殘的例子(稍後估計你就明白了),這裏的代碼就是咱們平時不少時候編程的大概思惟方式:類方法內部調用其餘方法,並且這個類是具體的,方法也是具體的,咱們當時想的只是:我要事先車這個功能,例如說,我只是要倒車入庫,我如今實現了,那就行啦,這樣代碼運行的不錯,恩,咱們開始沾沾自喜,感受本身幹了件大事,以爲java程序設計不過如此,簡單啦。設計模式
確實,上面這個例子,在現階段,很好地實現了咱們須要的功能,然而,然而,估計你是個程序員,你就會知道,需求,一直在變,程序也要一直變,正如個人上一篇討論設計模式的博客說到:咱們要保證咱們的設計具備可擴展性。架構
因此,看看咱們上面這個例子的可擴展性如何:加入,個人車不是普通的車,個人車是寶馬,寶馬啊,他媽的怎麼能和普通車同樣?個人run方法但是時速超過200km的,你怎麼能只是簡單地說我只是在往前走地描述個人駕駛狀態?因此,這是候,上面的代碼沒轍了,只能新建一個BMW類,而後乖乖地繼承car類,而後乖乖地重寫全部方法,而後,你會發覺:這個更高級別的car存在的意義彷佛並不大?下面是繼承後的BMW類的代碼:框架
class Bmw extends Car{ //我是寶馬,個人點火方法不同凡響 public void fire(){ System.out.println("我是寶馬,給我點火,個人發動機會開始轉動,而且哥點火時的氣勢可不是那些普通車可比的"); } //寶馬駕駛方法 public void run(){ System.out.println("我是寶馬,我如今在駕駛,注意,我是在飛奔駕駛,別將我和那些垃圾普通奇瑞qq類比"); } //寶馬倒車方法 public void backCar(){ System.out.println("我是車,我如今在倒車,由於我是寶馬,倒車姿式確定也不是通常酷"); } //如今要放好個人寶馬車了 public void setCar(){ //首先,轟轟,點火 fire(); //恩,向前飛奔,注意,是飛奔 run(); //ok,我要倒車入庫了 backCar(); //...固然,後續其餘操做:熄火啊什麼的 } }
因此,做爲程序員的你開始抱怨:爲毛感受父類在這裏沒什麼做用了?它做用表如今哪?我還不是要從新所有方法覆蓋一遍!因此,這時候,抽象類的威力就出來,下面看用抽象類改造後的例子;工具
2、抽象類進行更高層次的建模post
先看利用抽象類進行更高層次的建模吧,估計看完代碼你就大概能領悟抽象類再架構設計中是大概如何發揮做用的了:spa
//我是一個抽象的汽車類,注意,是抽象的 abstract class car{ //和上面例子同樣,我有下面這些方法,只不過,部分方法抽象化了 public abstract void fire(); public abstract void run(); public abstract void backCar(); //而後,下面這個方法不是抽象的(是的,java抽象類容許非抽象方法存在),由於,它對應全部的car都適用(也是高層次進行動做抽象的表現) public void setCar(){ //我調用抽象方法,不用擔憂,這些抽象方法會在子類中實現! fire(); run(); backCar(); } }
好了,有沒有領會到我大概要表達的意思和傳遞的思想了呢:在上面中,我就是利用car的抽象類,定義了setCar的具體方法,這是由於對應全部車來講setCar都是這幾個動做(fire,run,backCar),因此,這是肯定的——setCar必須確定是調用這幾個方法的,因此具體化;而fire,run,backCar針對不一樣的車有不一樣的方式,因此要抽象化,而後,子類只須要實現抽象類具體方法就好了,而後,對於全部的car來講,咱們能夠複用父類的setCar代碼(畢竟全部車的setCar動做同樣),而,這,不就是基礎的好處了嗎?好了,看下面的BMW傢伙在利用抽象類進行建模後的改進寫法:
class Bmw extends car{ public void fire() { System.out.println("我是寶馬,給我點火,個人發動機會開始轉動,而且哥點火時的氣勢可不是那些普通車可比的"); } public void run() { System.out.println("我是寶馬,我如今在駕駛,注意,我是在飛奔駕駛,別將我和那些垃圾普通奇瑞qq類比"); } public void backCar() { System.out.println("我是車,我如今在倒車,由於我是寶馬,倒車姿式確定也不是通常酷"); } //而後,咱們就能夠直接複用car父類中的setCar方法啦!直接調用便可,達到了複用代碼的目的! }
這時,估計你應該能體會到抽象類的一些威力了吧?它在更高的層次進行一個類組織的規範,這個抽象類知道大致上這個類該如何組織,如何運行,可是運行細節其實子類來決定的(子類實現對應抽象方法),這些,不正是不少web框架設計的經常使用手段嗎!
因此,架構就這樣來了,架構師在更高層次抽象系統的類之間、類內部的調度關係,而實現開發人員只須要實行具體的方法就能夠了,畢竟,類之間的關係,架構師已經規劃好了。
另外,這樣還有另外的好處就是:擴展性。我想新增一種車,只須要基礎抽象類Car便可,setCar操做會根據我新的類型的car的方法進行不一樣的內部動做,而我原來的代碼並不須要一點點的改變!這樣,符合擴展的不修改源代碼而利用新增代碼達到擴展的原則。
So,抽象類,的確,很不錯是吧,畢竟,雖然它不是具體的執行者(不能new),可是,它充當的確實帝王角色,專門負責指揮具體的方法去作事,因此我認爲:抽象類的設計,就是一套系統的架構規範的設計!