java之抽象類和繼承抽象類解讀
抽象類和繼承抽象類
抽象類不能直接實(shí)例化,需要?jiǎng)?chuàng)建一個(gè)指向自己的對象引用(其子類)來實(shí)例化
代碼:
public class Main { public static void main(String[] args) { /* People people = new People(); */ //錯(cuò)誤 People p = new Man(); p.eat(); p.drink(); /* p.palyGames() */ //此方法錯(cuò)誤 Man man = new Man(); man.eat(); man.playGames(); Women women = new Women(); women.eat(); women.dressing(); } abstract static class People{ String name; int age; float height; float weight; public void eat(){ System.out.println("人都會吃飯"); } public abstract void drink(); } static class Man extends People{ float short_hair; public void playGames(){ System.out.println("男的獨(dú)有的打游戲技能"); } @Override public void drink(){ System.out.println("man drink 酒"); } } static class Women extends People{ float long_hair; public void dressing(){ System.out.println("女的獨(dú)有的化妝技能"); } @Override public void drink(){ System.out.println("women drink 飲料"); } } }
這里People不能直接實(shí)例化,如果是People p = new Man();
這里p只能調(diào)用People類n抽象方法和成果調(diào)用了其抽象方法,則訪問的是其引用類(子類)
繼承的抽象類;
如果是Man man= new Man();
這里man是可以調(diào)用類Man和其繼承的抽象類People的方法和屬性
抽象類、普通類、接口的區(qū)別
概念:
抽象類和具體類是相對的概念。“抽象”是一種存在思想邏輯中的概念,而“具體”是一種可見可觸摸的現(xiàn)實(shí)對象。
簡單說,比如“人”比“男人”抽象一點(diǎn),“動(dòng)物”又比“人”更抽象一點(diǎn),而“生物”又比“動(dòng)物”更抽象。
抽象的概念是由具體概念依其“共性”而產(chǎn)生的,把具體概念的諸多個(gè)性排出,集中描述其共性,就會產(chǎn)生一個(gè)抽象性的概念。
抽象思維,是人類思維達(dá)到高級階段產(chǎn)生的一種能力,例如,當(dāng)小孩子思維尚未成熟時(shí),他們只能掌握具體概念,他們在學(xué)習(xí)代詞“你、我、他”時(shí)往往遇到困難,因?yàn)榇~具有較高的抽象性。
總之,抽象概念的外延大,內(nèi)涵??;具體概念的外延小,內(nèi)涵大。
一、抽象類與普通類
(1)普通類可以去實(shí)例化調(diào)用;抽象類不能被實(shí)例化,因?yàn)樗谴嬖谟谝环N概念而不非具體。
(2)普通類和抽象類都可以被繼承,但是抽象類被繼承后子類必須重寫繼承的方法,除非自類也是抽象類。
(3)實(shí)例演示:
public class Pet { public void play(){ //這是寵物類,普通父類,方法里是空的 } } -------------------------- public class Cat extends Pet { //這是子類,是一個(gè)貓類,重寫了父類方法 public void play(){ System.out.println("1、貓爬樹"); } } ------------------------ public class Dog extends Pet { //這是子類,是一個(gè)狗類,重寫了父類方法 public void play(){ System.out.println("2、狗啃骨頭"); } } ------------------------- public class Test { public static void main(String[] args) { //這是測試類,分別調(diào)用了子類的不同方法 Pet p1=new Cat(); //多典型的多態(tài)表現(xiàn)啊,相當(dāng)?shù)慕o力 Pet p2=new Dog(); p1.play(); p2.play(); } }
-----------------------
輸出結(jié)果:
1、貓爬樹
2、狗啃骨頭
-----------------------
問:
把父類改成抽象類,方法改成抽象方法,那么public void play(); 子類不變,依然重寫父類方法,那這個(gè)跟普通父類沒區(qū)別???難道說就一個(gè)抽象方法沒方法體就完事了??那我普通方法有方法體,我空著不寫內(nèi)容不就得了,不跟抽象方法一個(gè)樣嗎??別跟我說抽象類還不能實(shí)例化,哥也不需要去new它!普通類都能搞定的,還弄個(gè)抽象類有什么意義?我前面都說了普通類的方法我可以空著不寫,達(dá)到跟抽象類方法沒方法體一樣的效果。既然兩種方式都能達(dá)到同一個(gè)輸出效果,弄一種方式不就得了,那為什么還要?jiǎng)?chuàng)造出一個(gè)抽象類出來?難道是比普通類看著舒服?用著爽?還是更加便捷?還是為了強(qiáng)制讓別人用的時(shí)候必須強(qiáng)制化實(shí)現(xiàn)抽象方法省的你忘了什么的?
答:
就是為了強(qiáng)制不能實(shí)例化,以及強(qiáng)制子類必須實(shí)現(xiàn)方法這不是你忘不忘的問題,你說你不去new它就行了,這話沒錯(cuò)
那你想另一個(gè)問題,為什么要有訪問控制呢?為什么要有private和public之分呢?我可以全部public,不該訪問的,我不訪問就行了???小程序里,看不出什么區(qū)別,反而private成員要寫一堆set和get函數(shù),多麻煩,我自己寫小程序的時(shí)候也會偷懶全部public,但是項(xiàng)目大了,代碼多了,這種嚴(yán)謹(jǐn)?shù)慕Y(jié)構(gòu)就很重要了。且不說會有很多人合作一起寫一個(gè)程序,哪怕還是你一個(gè)人寫,也保不住有忘記的時(shí)候,那時(shí)候編譯器不報(bào)錯(cuò),茫茫碼海上哪找錯(cuò)誤去面向?qū)ο笳f到底就是方便你思考,易擴(kuò)展、易維護(hù)管理,硬要說沒必要,整個(gè)面向?qū)ο蠖紱]必要了,C語言有什么干不了的呀,運(yùn)行效率還高。
二、抽象類與接口
1、概念
接口是對動(dòng)作的抽象,抽象類是對本質(zhì)的抽象。
抽象類表示的是,這個(gè)對象是什么。接口表示的是,這個(gè)對象能做什么。比如,男人和女人,他們的抽象類是人類,而貓和狗的抽象類是寵物類。人類可以吃東西,寵物類也可以吃東西,但是兩者不能混為一談,因?yàn)橛斜举|(zhì)的區(qū)別。這個(gè)“吃東西”是一個(gè)動(dòng)作,你可以把“吃東西”定義成一個(gè)接口,然后讓兩個(gè)類去實(shí)現(xiàn)它的方法。
所以,在高級語言上,一個(gè)類只能繼承一個(gè)類或抽象類,正如人不可能同時(shí)是動(dòng)物類又是植物類,但是可以實(shí)現(xiàn)多個(gè)接口,例如,吃飯接口、呼吸接口等。
2、使用情況
- a.抽象類 和 接口 都是用來抽象具體對象的,但是接口的抽象級別最高;
- b.抽象類可以有具體的方法和屬性, 接口只能有抽象方法和不可變常量(final);
- c.抽象類主要用來抽象類別,接口主要用來抽象功能;
- d.抽象類中不包含任何實(shí)現(xiàn),派生類必須覆蓋它們。接口中所有方法都必須是未實(shí)現(xiàn)的;
- e.抽象類實(shí)現(xiàn)接口時(shí),接口的方法在抽象類中可以被實(shí)現(xiàn)也可以不被實(shí)現(xiàn),而普通實(shí)現(xiàn)接口必須實(shí)現(xiàn)所有接口方法。
3、使用方向
當(dāng)你關(guān)注一個(gè)事物的本質(zhì)的時(shí)候,用抽象類;當(dāng)你關(guān)注一個(gè)操作的時(shí)候,用接口。
總結(jié)
抽象類的功能要遠(yuǎn)超過接口,但是,定義抽象類的代價(jià)高。
因?yàn)楦呒壵Z言來說(從實(shí)際設(shè)計(jì)上來說也是)每個(gè)類只能繼承一個(gè)類。
在這個(gè)類中,你必須繼承或編寫出其所有子類的所有共性。
雖然接口在功能上會弱化許多,但是它只是針對一個(gè)動(dòng)作的描述。
而且你可以在一個(gè)類中同時(shí)實(shí)現(xiàn)多個(gè)接口。在設(shè)計(jì)階段會降低難度的。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一篇文章帶你搞懂Java線程池實(shí)現(xiàn)原理
線程池?zé)o論是工作還是面試都是必備的技能,但是很多人對于線程池的實(shí)現(xiàn)原理卻一知半解,并不了解線程池內(nèi)部的工作原理,今天就帶大家一塊剖析線程池底層實(shí)現(xiàn)原理2022-11-11SpringBoot整合Canal與RabbitMQ監(jiān)聽數(shù)據(jù)變更記錄
這篇文章主要介紹了SpringBoot整合Canal與RabbitMQ監(jiān)聽數(shù)據(jù)變更記錄,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-0910分鐘在服務(wù)器部署好Jenkins的詳細(xì)過程
這篇文章主要介紹了10分鐘在服務(wù)器部署好Jenkins,本文主要是?Jenkins?的安裝部署,那前提我們應(yīng)該裝好?Git?Maven?JDK,準(zhǔn)備工作本文不給大家詳細(xì)介紹了,對服務(wù)器部署Jenkins相關(guān)知識感興趣的朋友一起看看吧2022-08-08Java開發(fā)環(huán)境不再需要配置classpath問題
這篇文章主要介紹了Java開發(fā)環(huán)境不再需要配置classpath問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12