java零基礎(chǔ)入門-面向?qū)ο笃?/b>(十二)? 抽象類
抽象類這個(gè)玩意,理解起來費(fèi)點(diǎn)勁。我們從字面意思開始吧。
抽象一詞的本義是指人在認(rèn)識思維活動中對事物表象因素的舍棄和對本質(zhì)因素的抽取。說人話就是刪除看的懂得,留下看不懂的。
應(yīng)用于美術(shù)領(lǐng)域,便有了抽象性藝術(shù)、抽象主義、抽象派等概念。
來看一個(gè)著名的抽象派作品。

84歲的美國藝術(shù)家羅伯特·雷曼1961年創(chuàng)作的油畫《無題》,以折合人民幣8000萬至1.2億元的價(jià)格拍賣。
我感覺這畫跟我家衛(wèi)生間的瓷磚有點(diǎn)像,莫非我家的還是個(gè)抽象派衛(wèi)生間不成...
至于抽象類,它和抽象畫還真的有點(diǎn)相似之處
抽象畫:我告訴你我畫了一幅畫,具體畫的啥,我也不知道!
抽象類:我告訴你我定義了一些方法,方法具體做什么,我也不知道!
為什么要抽象類
畫家分為很多流派,以我淺顯的藝術(shù)知識,大概分得清楚三個(gè)流派的畫家,抽象派,印象派,立體派。
現(xiàn)在確定了父類 - 畫家,然后三個(gè)子類 抽象派畫家 , 印象派畫家,立體派畫家去繼承畫家這個(gè)類。畫家類里面有一個(gè)方法,畫畫,這個(gè)方法是必須有的。
好了,問題出現(xiàn)了,當(dāng)我們使用父類 - 畫家創(chuàng)建對象,然后調(diào)用 畫畫這個(gè)方法的時(shí)候,它應(yīng)該畫出來的是哪個(gè)流派的畫?
是不是懵圈了?你就給我個(gè)畫家,也沒問人家是哪一派的,就拉著人家畫畫,鬼知道他畫的啥。

這說明一個(gè)什么問題?如果我們將某一部分事物的特征抽取出來,定義成了父類,其實(shí)這個(gè)父類是具有指導(dǎo)性的,而不是可實(shí)現(xiàn)性。
說人話,你非要將畫家提出一個(gè)父類,那么就不要在父類里面實(shí)現(xiàn)方法,也就是不要在父類里面寫代碼邏輯。因?yàn)楦割惒⒉恢浪约罕粚?shí)例化以后,該如何實(shí)現(xiàn)方法。
比如這個(gè)畫家,如果不是畫家的子類,具體到某個(gè)流派的畫家,在畫家這個(gè)類里面實(shí)現(xiàn)畫畫這個(gè)方法是毫無意義的。他不知道該畫個(gè)什么流派的畫出來。我們只會使用子類重寫的畫畫方法,而不會使用父類的畫畫方法。

有同學(xué)肯定有疑問,既然我們不使用父類里面的畫畫方法,刪掉不就行了?只在子類里面寫畫畫的方法不就行了?
那么我請問你,你見過連畫畫都不會的畫家嗎?畫家這個(gè)類沒有畫畫這個(gè)方法,就算代碼不錯(cuò),你的類的設(shè)計(jì)就是錯(cuò)的。類是對實(shí)際事物的抽象,這個(gè)是原則。
那該怎么做?
這時(shí)候就該抽象方法登場了。把畫畫這個(gè)方法定義成抽象方法,畫家父類并不實(shí)現(xiàn)任何代碼,而是留給子類去實(shí)現(xiàn)他。你是什么派的畫家,畫畫的方法就畫什么派的畫就行了。

看到了沒有,抽象方法的核心思想就是 啥也不做~ 具體要做的,用子類去實(shí)現(xiàn)抽象方法即可。
抽象類的清規(guī)戒律
1.抽象方法不能被調(diào)用。
2.一個(gè)類被定義為抽象類以后,就不能使用new關(guān)鍵字新建對象了。
3.抽象類的子類必須重寫抽象方法。
這三個(gè)規(guī)則放在一起,因?yàn)樗麄?b>環(huán)環(huán)相扣。為了方便記憶,我們用代碼來講解。
首先看報(bào)錯(cuò)情況。

1.因?yàn)槌橄蠓椒]有方法體,啥也不干,所以不能調(diào)用抽象方法,因?yàn)檫@樣做毫無意義。
2.假設(shè)可以實(shí)例化抽象類,那么就可以用抽象類的對象去調(diào)用什么也干不了的抽象方法,這樣違背了第一條原則。
3.如果繼承了抽象類,而又不去重寫(實(shí)現(xiàn))抽象類的抽象方法,會發(fā)生什么?因?yàn)樽宇悰]有實(shí)現(xiàn)父類的抽象方法,那么用子類對象就可以調(diào)用到父類的抽象方法,這樣也違背了第一條原則。

4.抽象類可以包含普通方法和構(gòu)造器。抽象類就是專門用來被子類繼承的,如果子類都有一個(gè)不必被重寫的方法,那么可以將它定義在父類里面,每個(gè)子類都可以調(diào)用他。構(gòu)造器也一樣,可以被子類復(fù)用。
比如畫家除了畫畫這個(gè)抽象方法以外,還可以有賣畫這個(gè)方法,上面那位大師的一幅畫可是賣了幾千萬。每個(gè)畫家都可以賣畫,自己不去實(shí)現(xiàn),就調(diào)用父類的方法。構(gòu)造器也是一樣,可以用super調(diào)用抽象類的構(gòu)造器,大家可以自己實(shí)現(xiàn)一下。
舉個(gè)栗子
說了半天抽象類,下面再舉個(gè)例子幫助大家更好的理解一下。
來來來,需求講解一下,現(xiàn)在要做三個(gè)功能,請假,加班,外出,原型圖如下。如果是你你會怎么做?
如果我們沒有一點(diǎn)點(diǎn)的抽象能力,肯定會說,這還不簡單,做三個(gè)功能唄。
但是我們現(xiàn)在可是學(xué)過抽象類的人了,怎么能做這么不優(yōu)雅的事,我們必須要有設(shè)計(jì)的概念。

我們觀察了原型圖以后,可以看到,紅色框中的內(nèi)容,是三個(gè)功能都有的。不管你是請假,外出,還是加班,都需要一個(gè)人來對你的請求進(jìn)行審批。這個(gè)是必須的(前面有個(gè)紅色星星)。
而審批轉(zhuǎn)聊天功能和抄送功能都是非必須的,可以不填。
再看藍(lán)色框框,請假事由必須填,照片可以不填。
外出事由是必須填的,沒事別亂跑,好好上班。
加班事由可以不填,叫你加班還需要理由么?
分析過后,我們總結(jié)一下,紅色框里的是相同的功能可以提出來復(fù)用,而藍(lán)色框是每個(gè)功能獨(dú)有的。
我們看看用抽象類的高端玩家和不用抽象類的普通玩家是如何設(shè)計(jì)以上功能。

普通玩家設(shè)計(jì)了三個(gè)功能,自己體會。

高端玩家抽象了一個(gè)抽象父類,這樣設(shè)計(jì)還有一個(gè)優(yōu)點(diǎn)。如果像普通玩家一樣設(shè)計(jì)三個(gè)獨(dú)立的類,那么可能會漏掉功能,比如說在請假單里面,忘記寫add_reason這個(gè)方法,這是有可能發(fā)生的。
而如果設(shè)計(jì)成子類繼承抽象父類,則不會發(fā)生這種情況,因?yàn)槌橄蠓椒ū仨殞?shí)現(xiàn),不然就報(bào)錯(cuò)。這也是用抽象類來規(guī)范子類的一個(gè)好方法。
請好好理解本章內(nèi)容,因?yàn)橄乱徽?,會介紹一個(gè)比抽象類更抽象的一個(gè)知識點(diǎn),請做好準(zhǔn)備。