面向對象 - Java那些事兒

面試的時候,面試官問,你是怎麼理解面向對象的編程?我想不少人會照着面試題來背吧,面向對象呀,不就是繼承,封裝,多態嗎?注意,面試官問到這裏,是想聽聽你對面向對象的理解,而不是讓你來背概念。面試

面向對象,是對現實世界的模擬,下圖咱們簡單模擬了一個動物世界。編程

面向對象的三個基本特徵之一繼承,這裏Primat繼承了Animal,Person繼承了Primat,繼承很簡單,就很少說了,看如下代碼實現,代碼中的註釋比較重要,請重點看post

在代碼中,不論是動物,鳥類,人類,猴子,咱們均可以抽象成類,類是對象的模板,經過new關鍵字,能夠建立一個個對象。仔細看藍色框裏的內容,animal1和animal2,雖然都是同一個形態(Animal),因爲指向的是子類對象,當調用同一個eat()方法,運行時會智能匹配到子類的實現,最後獲得的結果也不同,這種形爲,咱們稱之爲多態。3d

多態要知足三個條件。cdn

1、要有繼承;(Person繼承了Animal,Monkey也繼承了Animal)
2、要有重寫;(都重寫了父類的eat方法)
3、父類引用指向子類對象。(紅框內容)對象

再看下圖,利用IDE的代碼聯想功能看一下,person4這個對象能訪問到name、sex屬性,eat()、printAge()方法,但沒法訪問age屬性,isLady()方法。是由於咱們在該屬性和方法前面加了private關鍵字。隱藏了不想對客戶端暴露的age屬性和isLady()方法(這裏的客戶端是main方法),可是咱們對客戶端提供了一個printAge方法來打印年齡,但在打印年齡前,咱們對年齡作了一系列處理(不打印女士年齡)。blog

對於這種隱藏對象屬性和實現細節,僅對外公開指定方法來控制程序中屬性的訪問和修改,咱們稱之爲封裝。(這兒咱們沒有對age提供set方法,壓根無法修改,提供了一個printAge()方法供外部訪問)。繼承

在工做中,咱們可能會有這麼一個需求,當Person對象的名字一致,年齡一致,性別一致,就當成同一人處理。若是以前看過我 說說Java裏的equals(上) - 知乎專欄 一文的人,你們應該不會用==或equals直接去作比較,如下是結果。接口


當用==和equals失敗後,開發者可能會寫下如下代碼去作判斷開發

寫到年齡邏輯的時候發現,因爲age屬性是私有的,又沒有提供getAge( )方法,獲取不到age屬性,可能會在Person這個類裏提供一個getAge( )方法或把age的private關鍵字去掉,這樣雖然也能完成邏輯,但會致使後續使用該類的人不再調printAge去打印age了,而是直接訪問age屬性或getAge( )方法去打印,女士的age也就暴露了出去。很顯然,這種作法打破了咱們以前對age的封裝,不建議這麼作

age是私有的,那咱們把這段代碼挪到Person對象裏不就好了?好主意,比較兩個對象是否相等,不該該由客戶端來決定,而是由對象自己來決定。這也是面向對象的技巧之一。

有了以上思路,咱們在Person裏擴展了一個方法,

一切彷佛很完美,結果也和咱們指望的同樣,問題彷佛解決了。

咱們知道Set裏的元素無放入順序,元素不可重複,請思考如下代碼的執行結果:

但願看完本章後,讀者對面向對象有了本身的一些見解和思考,而不是面試題中一味出現的六個字,多態,繼承,封裝。甚至你能夠對面試官莞爾一笑,啊,我還沒對象,有大把的時間投入到工做中來。

評論區裏,有人說Animal,Primat應該聲明爲抽象類而不是接口,其實兩種方式都是能夠的。若是Animal暫時不肯定有屬性或有具體的形爲,建議先聲明成接口,由於一個類能夠實現多個接口,但只能繼承一個類,聲明爲接口更靈活一些,也使實現類具備更好的擴展性

注:本專欄文章首發於公衆號:saysayJava。全部示例代碼均已上傳至公衆號,須要請關注下載。

若是喜歡本系列文章,請爲我點贊或順手分享,您的支持是我繼續下去的動力,您也能夠在評論區留言想了解的內容,有機會本專欄會作講解,最後別忘了關注一下我。

轉載無限歡迎,但請註明「做者」和「原文地址」。轉載請在文中保留此段,感謝您對做者版權的尊重。如需商業轉載或刊登,請聯繫做者得到受權。

上一篇:Java自動裝箱/拆箱 - Java那些事兒

下一篇:說說Java裏的equals(中)- Java那些事兒

相關文章
相關標籤/搜索