程序员过关斩将-- 工作好多年可能还未真正了解接口和抽象类
點擊上方“藍字”關注我們
菜菜哥,我偷偷出去面試了,然后面試官讓我回來等消息
那你可能掛了呀,有什么問題沒回答上來嗎
確實有一個問題回答的不太好哎,就是接口和抽象類
這個確實是面試官比較愛問的題目之一
那能不能說說接口和抽象類的區別呢?
可以哦,順便還可以再延伸一下,先拋幾個問題哦
1. 抽象類和接口的定義和區別?
2. 抽象類在面向對象編程中解決了什么問題?
3. 接口在面向對象編程中解決了什么問題?
4. 如何決定該用抽象類還是接口?
5. 如果使用的語言不支持抽象類和接口,該如何應對?
抽象類
在面向對象編程的語言中,多數都添加了對抽象類和接口的支持,比如最常用的java,C#等語言。
//抽象類public?abstract?class?Human{//抽象方法public?abstract?string?Gender();//屬性public?string?Name?{?get;?set;?}//方法public?int?GetAge(){return?1;}}以上是一個普通的抽象類的定義,具體怎樣使用,度娘有一大堆結果,其實總體來說抽象類主要有以下幾點特征:
1. 抽象類不能被實例化,只能被繼承。也就是說如果 New Human()會報編譯錯誤
2. 抽象類也是類,可以包含屬性和方法,方法可以包含實現,也可以不包含,不包含實現被稱為抽象方法。
3. 子類繼承抽象類,必須要實現定義的所有抽象方法,不然編譯器會報編譯錯誤。
抽象類本質上還是類,只不過是一種不能被實例化的特殊類而已,但是在面向對象的設計過程中卻起著非常重要的地位,本質上抽象類體現的是is-a的關系,就像上邊定義的抽象類一樣,Human類型抽象的是人類,假如我定義一個菜菜的類型來繼承這個類型?
?public?class?CaiCai?:?Human{public?override?string?Gender(){return?"男";}}CaiCai這個類必須要提供抽象方法的實現才可以通過編譯。抽象類的產生是面向對象開發思想的延伸,是解決代碼復用問題的一個方案,更是把代碼進行抽象化的一個結果。抽象類的設計思想是自下而上的,也就是說設計上應該先有子類,當子類逐漸增加,進而抽象出共用特性而產生抽象類。
說到這里,好多同學會問,如果我不用抽象類做父類也可以啊。不錯,普通的類當然也可以代替抽象類的地位。但是有幾點就看起來比較奇怪了
1. 父類也可以進行實例化了,但是其中要抽象的方法看起來就比較怪了,因為這些方法只有子類中才有明確的定義,比如 以上代碼中Human這個類如果修改為普通類型,那方法Gender()該返回什么內容呢?
2. 在編譯期間,如果子類沒有實現父類的方法是不會報錯的,這就加大了排查問題的難度,如果需要重寫的方法很多,之后排查問題會非常頭疼
3. 抽象出來的父類如果可以被實例化,這本質上違反了面向對象的思想,畢竟父類是一個抽象化的概念,被實例化之后代表著什么比較令人困惑
接口
接口在系統設計中,最重要的作用就是解耦。你應該聽過不止一次的“面向接口編程”和依賴倒置等思想,這些也是面向對象設計思想的一種體現。接口本質上是抽象出來的對象的行為,或者叫做契約。在面向接口開發中,調用者不關心接口的實現,而是依賴于接口的定義,接口定義的穩定性代表著一個系統的穩定性,如果一個系統對外的接口定義有問題,那這個系統多半是會死人的。
????public?interface?IHuman{//接口行為定義void?Walk();}以上只是一個簡單接口的定義而已,接口的抽象小到可以是一個對象的行為抽象,大到可以是一個服務的行為抽象,更有可能是一個系統的行為抽象,所以接口是一個很泛的概念,但是本質上還是反應的是面向對象設計理念。由于接口是行為的定義,所以就決定了它有以下特點
1. 接口只能定義行為,不能包含行為的實現
2. 類型繼承接口的時候,必須要實現接口的所有行為
3. 接口不同于類,不能包含屬性
由于接口體現的是行為準則,所以接口在定義的時候也可以利用面向對象設計理念,當多個不同接口定義了相同的行為,可以考慮抽象出更上層的接口來實現行為的復用。
寫在最后
抽象類和接口都是對象的抽象行為產生的,只不過抽象類更加側重于 is-a 的關系,它實現了代碼復用,而接口更加側重于行為的抽象(has -a),舉一個很簡單的栗子,如果設計一個鳥類的抽象該怎么做呢?不同的鳥可能羽毛的顏色不一樣,像這樣的屬性可以利用抽象類,不同的鳥類可能會有不同的飛行行為,這樣行為類的抽象利用接口來實現更加合適。
無論是接口還是抽象類,在代碼層次上體現的是上下級關系,就算一個編程語言沒有提供接口和抽象類的定義,只要能實現對象上下級關系,原理上也可以實現面向對象編程。編程的抽象思想始終在圍繞著上下,內外這幾個維度在合理的進化著。
說到接口的定義,其實還可以在泛化一下,接口中只有行為方法的定義,在一些不支持接口的編程語言中,可以把只包含方法的類看做接口的抽象定義,這在設計理念上是說的通的。
在繼承層次上和設計流程上,抽象類是一種自下而上的設計思路,先有子類的代碼,當子類逐漸增多,才會抽象出更加上層的父類。而接口不同,面向接口編程是一種自上而下的設計思路,先抽象出行為契約,然后才是實現。
完
●程序員過關斬將-- 噴一噴坑爹的面向UI編程
●程序員過關斬將--redis做消息隊列,香嗎?
●程序員修神之路--有了容器為什么kubernetes還需要Pod?
●程序員修神之路--為什么我會了SOA,你們還要逼我學微服務?
●程序員過關斬將--要想獲取我的用戶信息,就得按照規矩來
●程序員過關斬將--更加優雅的Token認證方式JWT
●程序員過關斬將--cookie和session的關系其實很簡單
●程序員修神之路--用NOSql給高并發系統加速
●程序員修神之路--高并發系統設計負載均衡架構
●程序員過關斬將--你為什么還在用存儲過程?
●程序員修神之路--問世間異步為何物?
●程序員修神之路--提高網站的吞吐
長按添加菜菜好友
關注后回復:“大禮包”和“福利”,領取驚喜
總結
以上是生活随笔為你收集整理的程序员过关斩将-- 工作好多年可能还未真正了解接口和抽象类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现一个基于动态代理的 AOP
- 下一篇: 扫盲消息队列 | 消息中间件 | Kaf