Java為什麼要區分extends和implements?

段槿年


不請自來~

extends和implements都是Java最基礎的知識點,本來沒有必要回答這個問題,但是看了一下別人的答案,基本上還是講基本的概念,唸書誰不會啊,都沒有講到兩者的真正作用,特別是implements,我給大家分享分享我的體會。


解耦

implements的重要作用之一,就是為了解耦。這是什麼意思呢,給大家舉個例子。

由於Java的多態,接口的調用者,只需要調用接口就好了,具體接口中的功能,就讓接口的實現者去實現好了。這樣的好處是,避免接口的調用方直接參與接口邏輯的實現,避免調用方和實現方的關係過於緊密(修改或增加實現方的時候,還需要修改調用方的代碼),這就是解耦。要注意:

  • 如果一個接口就一個實現的話,沒有必要過度設計,只會加大代碼的複雜程度(不過需求未來的變化,是預測不到的)。

  • 只有一個實現的話,也會存在遷移的問題,比如現在使用的Oracle數據庫,準備遷移到Mysql數據庫上,使用面向接口編程的話,只修改數據庫相關的實現即可。

  • 接口的實現不是new出來的。

舉個例子(可能不是非常恰當,主要為了理解),這幅圖大家應該很常見吧,這個是今日頭條的登錄頁面:

QQ、微信都是第三方登錄,那麼應該設計好接口,QQ登錄是一個實現,微信登錄是一個實現;如果未來支持微博登錄的話,那麼就在增加一個實現。然後通過工廠模式獲得對應的實現類,而不是直接在代碼中寫:if(登錄方式選擇QQ){實現}。


設計和實現分離

implements另外一個重要的作用,就是讓設計和實現分離。制定好標準,可以讓調用方和實現方各做各的,互不影響;也可以讓不同的實現方,都用一個標準來實現,避免調用方的改動。

用JDBC舉例,很容易理解(使用Mysql舉例):

  • 我們只看這一句:DriverManager.getConnection(URL,user,password);

  • JDBC連接Mysql和其他數據庫的實現細節肯定不一樣,如果都讓java實現的話,每一種數據庫都要兼容,這是不可能的。

  • 如果完全讓每個數據庫的實現方寫,mysql的連接方法名叫getConnect,DB2自己寫的時候叫getCon,誰也不服誰,都覺得自己是最優的,這時候調用方就麻煩了。

  • Java(最早是sun公司)一看不行,我給你們規定好吧,都叫getConnection,你們就按照我的寫,我提供接口,你們實現。

  • 於是,當通過JDBC連接Mysql的時候,需要引入mysql的jar包,可以看到其中的代碼都是實現了java.sql.Driver:

另外說兩點

  • 一流的公司做標準,這句話好理解了吧。

  • 軟件生態圈很重要,一方面的意思就是:Java做的牛了,出個JDBC的標準,各個數據庫廠商都爭著實現,咱自己編個啥語言出個接口,看人家理不理。

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


會點代碼的大叔


這是一個非常好的問題,在Java的學習和認知過程中,好的問題能讓學習者迅速掌握Java語言的脈絡從而建立Java編程思維。

那麼Java為什麼要區分extends和implements呢?在我看來有以下幾點原因:

第一,定位不同。extends的定位是“擴展”(類擴展類、接口擴展接口),而implments的定位是“實現”(類實現接口)。在Java中,擴展是同一類事務之間的關係,而實現則是實體和抽象之間的關係。但是這裡面有一個例外,那就是“抽象類”,抽象類也稱為“半抽象”,其實抽象類採用implments在邏輯上也是能講得通的,但是Java為抽象類賦予的定義是“類”而不是“接口”,所以這也就能說得通了。

第二,用法不同。extends可以用於類與類之間,也可以用於接口與接口之間,但是extends用於類之間與用於接口之間是不同的。extends用於類之間更傾向於繼承,而用於接口之間更傾向於擴展,繼承只能是單繼承,而擴展則可以多擴展。implements則是類與接口之間的應用(實體與抽象之間的應用),一個類可以同時實現多個接口而不影響結構的清晰性。

第三,表現不同的面向對象思想。Java當中extends與implements與多態的關係非常密切,可以說沒有這兩個關鍵字就沒有多態。但是這兩個關鍵字體現的卻是不同的面向對象思想,一個強調拿來主義,另一個則強調按標準辦事(抽象也往往稱為標準)。

其實extends與implements之間也有相同的地方,比如都是對體系結構的表述,也都可以完成屬性的傳遞等。

我在頭條上寫了關於Java學習的系列文章,如果大家感興趣的話,可以關注我的頭條號並查看,如果有關於Java編程方面的問題,也可以諮詢我,謝謝!


IT人劉俊明


這個問題涉及到面向對象的三個基本概念(繼承,多態,封裝)中的繼承和多態。請聽我慢慢道來。

繼承

究其本質繼承有兩個目的。

  • 統一接口使子類可以被重載,這是通過抽象類(Abstract)實現的。在講到多態的時候,再詳細說說接口的應用。
  • 由父類保證子類的一致性,這是通過extends實現的。教科書上喜歡用貓狗繼承了動物的共性來解釋子類繼承父類的概念。我倒認為這個說法容易導致混亂。講一個真實的事例,我需要對同一組數據做兩種輸出報表,一個是網頁而另一個是Excel報,重要的事情是保證這兩個報表的數據一致。因此需要把數據部分做成父類,輸出部分做成兩個子類。可我的程序員只考慮了報表這一共通屬性,反其道而行之,做出來的程序Bug無數致使項目一度失控。

多態

多態的目的是實例化時可靈活加載不同的類而無需變更接口。這是面向對象程序語言的一大特色。多態有兩種實現方法。

  • 定義抽象類通過多個子類的繼承實現多態。這個方法的好處是可以保證子類處理的一致性。這一點在上面已經解釋過了。這樣的重載被限制在單一的父類上,有些不夠靈活。
  • 定義interface通過多個類的implements實現多態。這個方法可以最大限度地把多態的特性發揮出來。需要注意的是,雖然類的接口相同但處理是完全獨立的。

兩個實現重載的方法各有利弊,可根據需要靈活運用。

小結

概括起來,extends實現了繼承,implements實現了多態,對Java來說兩個語句都很重要,不可或缺。通過運用繼承和多態這兩個特性,以Java為代表的面向對象的程序語言可以實現程序架構的繼承(抽象工廠模式是個典型的例子),在構建大型系統方面展現了巨大的優勢。

對設計模式有興趣的小夥伴可以提出問題,我有很多故事可以分享哦。


日衝信息 黃


作為一個C#的程序員我來解釋下。

其實在C#領域是可以extends多個類的這點和java不同,但是依舊有implements。

所以說這個設計是為了多繼承是很片面的,因為Cs能做的繼承多個類Java設計者肯定也可以做到。

言歸正傳。一般說繼承,主要是抽象類和實體類。類的特點就是,有屬性,有方法,可以把功能拋給子類實現也可以自己提供通用屬性和方法給子類服務。也就是說,所有的子類都具備了父類的特徵,都是需要藉助父類幫助才能實現功能的類,父親給了子女呵護,但是同時,也有父親強加給子女的東西。一開始父親只是滿足孩子的想法,後來父親一想,天冷了,要穿秋褲。然後給在子女未知的情況下買了一堆秋褲。甭管你喜不喜歡,你必須穿著就對了。

我對接口的理解就是說明與目錄,我要幹某件事,但是我不知道步驟,於是接口告訴我你需要準備什麼就行了。我一看能接受,就去做了,自己砍柴,自己挑水,雖然辛苦,但是怎麼做的都是我掌握的。忽然,有一天目錄上突然添了一項,穿秋褲,添加人告訴我,要麼你穿秋褲,要麼你換其他秘籍試試?要麼你隨便應付下,不過後果自負。不管怎麼說,你給個交代。選擇權完全在子類手上,你可以和大家一樣,也可以做不一樣的煙火,你只要應付完接口交代你做的事,沒有什麼能控制你的。

碼了那麼多,好像跑題了?算了,就這樣吧。


小汐vivi


首先先理解這兩個關鍵字,

extends是類繼承類 接口繼承接口的關鍵字

implement是類實現接口的關鍵字

java中很重要的一個思想多態就涉及這兩個關鍵字 從多態入手

多態的前提是:

1 繼承(實現父接口)

2重寫

3向上轉型

如果父類是實體類 那麼子類就使用extends 繼承父類 因為沒有抽象方法

如果父類是接口 那麼子類就使用implement實現父類 實現父類中的所有抽象方法

我是一個在校大學生 可能講的不是太明白,見諒😂


好名字都讓豬起了27


如果題主是學java編程,這樣的問題並不好(原因後面解釋)。如果是挑戰java規範,答案就簡單了,者就是一種設計。

java語言誕生於面向對象編程理論與實踐都相對成熟的年代。java語言開發者改良了對象多重繼承思想,代之以可以擴展(extends)的接口(interface)。接口的方法缺省條件下是抽象的(aberstract)。

一個類(class)可以實現(implements)0到多個接口,但是隻能擴展(extends)一個類。你覺得(implements)和(extends)的語義上有重疊嗎?

說這個問題不好的原因是,只有上來就試圖通過調試代碼來學習java語言,才會遇到題主的問題吧?最簡單的java語法介紹都會說到本文前邊的語法特點吧?


井151276607


我發現,編程語言中的很多東西其實是為了防止學渣挖坑。為了引導學渣少挖坑多鋪路,java平臺推出特殊的抽象類(接口),要求開發者繼承(實現)特殊的抽象類(接口)時必須重寫所定義的方法。


分享到:


相關文章: