Java是當(dāng)今最流行的面向?qū)ο缶幊陶Z言之一。由于它是獨(dú)立于平臺(tái)的,因此您可以在每種類型的設(shè)備和每個(gè)操作系統(tǒng)上找到 Java 應(yīng)用程序。而且由于Java相對(duì)容易學(xué)習(xí),因此它是許多程序員學(xué)習(xí)的第一批語言之一。
您應(yīng)該熟悉的 Java 的一個(gè)重要特性是類繼承。繼承允許程序員通過促進(jìn)類重用來優(yōu)化代碼。如果可以重用已經(jīng)過測(cè)試和調(diào)試的代碼,軟件開發(fā)生命周期將變得更短且成本更低。
雖然理論上是一個(gè)簡單的概念,但編碼繼承關(guān)系需要注意細(xì)節(jié)。對(duì)于多重繼承尤其如此,其中單個(gè)子類從多個(gè)父類繼承屬性。
Java拒絕多重繼承關(guān)系,因?yàn)樗鼈儠?huì)產(chǎn)生歧義,但是如果您知道該怎么做,有幾種方法可以實(shí)現(xiàn)許多相同的效果。
在本文中,我們將研究多重繼承的問題,并討論Java中的替代編碼選項(xiàng)。
繼承術(shù)語
有時(shí),要成為一名成功的程序員,你必須學(xué)會(huì)解決問題,以便找到常見錯(cuò)誤或問題的解決方法。這是安全智能編碼的必要部分。
其中一個(gè)問題涉及Java中的多重繼承(或者更確切地說,缺乏多重繼承)。
要完全理解 Java 中的繼承,您需要熟悉基本的面向?qū)ο缶幊?(OOP) 繼承術(shù)語。
類: 類是面向?qū)ο缶幊陶Z言中的基本模板結(jié)構(gòu)。類定義一組對(duì)象的公共屬性。
父類:父類也稱為基類或超類,是為子類提供功能的可擴(kuò)展類。這就是可重用性發(fā)揮作用的地方。創(chuàng)建子類時(shí),將重用父類定義和函數(shù)。
兒童班:更一般地稱為子類,子類從另一個(gè)類繼承特征。子類是擴(kuò)展類或派生類。
遺產(chǎn):父類和子類之間的關(guān)系。
輸出讀取繼承類型
目前有許多流行的面向?qū)ο缶幊陶Z言在使用,包括 Java、C++、JavaScript、Python、PHP、Ruby 和 Perl。雖然繼承是這些 OOP 語言的常見概念,但并非所有繼承類型都存在于每種語言中。
了解您正在使用的特定語言中的一般繼承類型和繼承限制至關(guān)重要。您對(duì)繼承的了解越多,您就越能有效地成為一名軟件開發(fā)人員。
Java 支持的繼承類型包括:
單級(jí)繼承:當(dāng)子類從單個(gè)父類派生功能時(shí)。
多級(jí)繼承:這是單級(jí)繼承的分層形式。在多級(jí)繼承中,子類還可以充當(dāng)其他子類的父類。每個(gè)級(jí)別之間的關(guān)系都是線性的 - 沒有分支像多重繼承那樣延伸到上面。然后,最終的子類具有其上方每個(gè)級(jí)別的功能。
分層繼承:與多重繼承相反。在分層繼承中,單個(gè)父類具有多個(gè)子類。因此,它不是在上面有分支,而是在下面分支。
混合繼承:顧名思義,混合繼承是其他繼承類型的組合。
除了上面的繼承類型之外,Java 還支持其他類型。
多重繼承:在多重繼承中,一個(gè)子類具有多個(gè)父類。雖然 Java 和 JavaScript 不支持多重繼承,但 OOP 語言(如C++支持多重繼承)
多路徑繼承:多級(jí)、多級(jí)和分層繼承的混合體,在多路徑繼承中,子類從父類和父類的多個(gè)子類派生其特性和功能。因?yàn)槎嗦窂嚼^承依賴于多重繼承,所以 Java 不支持它的使用。
為什么 Java 不支持多重繼承
多重繼承的主要問題是,它有可能在子類中產(chǎn)生歧義。在1995年的概述白皮書中,Java首席設(shè)計(jì)師詹姆斯·高斯林(James Gosling)指出,多重繼承的問題是創(chuàng)建Java的動(dòng)機(jī)之一。
多重繼承所固有的困難在鉆石問題中表現(xiàn)得最為明顯。在菱形問題中,父類 A 有兩個(gè)不同的子類 B 和 C;也就是說,子類 B 和 C 擴(kuò)展了類 A。
現(xiàn)在我們創(chuàng)建一個(gè)新的子類 D,它同時(shí)擴(kuò)展了類 B 和類 C.請(qǐng)注意,我們有多重繼承(D 擴(kuò)展 B 和 C)、分層繼承(B 和 C 擴(kuò)展 A)和多級(jí)繼承(D 擴(kuò)展 A、B 和 C)。
在菱形問題中,子類 B 和 C 從父類 A 繼承方法。B 和 C 都重寫繼承的方法。但是B和C中的新方法相互沖突。
終極子類 D 從其多個(gè)父級(jí) B 和 C 繼承兩個(gè)獨(dú)立且沖突的方法。不清楚應(yīng)該使用哪種方法類D,因此存在歧義。其他 OOP 編程語言實(shí)現(xiàn)了各種方法來解決多重繼承歧義。
如何解決Java中的多重繼承問題
僅僅因?yàn)槎嘀乩^承有問題并不意味著它沒有用。在許多情況下,您可能希望一個(gè)類具有來自其他多個(gè)類的功能。
想想當(dāng)你成為一個(gè)非常成功的軟件開發(fā)人員時(shí),你會(huì)買到特斯拉跑車。它將從跑車類和電動(dòng)汽車類中汲取特征。
或者,也許您正在使用私有瀏覽器閱讀本文,該文章具有在線數(shù)據(jù)隱私解決方案類和常規(guī) Internet 瀏覽器類的功能。
但是你不能在Java中擴(kuò)展多個(gè)類。那么Java如何處理多重繼承問題呢?
好吧,它使用稱為接口的結(jié)構(gòu)。接口是抽象類型,用于指定要實(shí)現(xiàn)的類的行為。由于它們是抽象的,因此接口不包含有關(guān)其行為的詳細(xì)說明。相反,這些類提供了接口行為的具體實(shí)現(xiàn)。
接口具有以下幾個(gè)定義特征:
與類不同,您不實(shí)例化接口。相反,類實(shí)現(xiàn)接口
接口僅包含公共常量定義和方法標(biāo)頭
接口只能擴(kuò)展其他接口,而不能擴(kuò)展類
接口可以擴(kuò)展多個(gè)接口,類可以實(shí)現(xiàn)多個(gè)接口
現(xiàn)在,我們可以有效地繞過接口的菱形問題?;叵胍幌拢挥薪涌谥荒軘U(kuò)展其他接口,并且任何需要多個(gè)繼承特征的類都必須實(shí)現(xiàn)多個(gè)接口,我們可以重新定義菱形問題類。
以前的類 A、B 和 C 現(xiàn)在變成了接口 A、B 和 C.接口 B 和 C 仍然擴(kuò)展了接口 A,但這些接口中沒有具體的函數(shù),只有定義的行為。類 D 仍然是一個(gè)類,它負(fù)責(zé)接口 B 和 C 中的行為的具體實(shí)現(xiàn)。
請(qǐng)注意此處的一個(gè)關(guān)鍵區(qū)別:D 類不是擴(kuò)展接口 B 和 C。相反,它正在實(shí)施它們。因此,您實(shí)際上沒有多重繼承。相反,你只是重新定義了問題。
了解繼承對(duì)于任何有效的編碼人員都是必要的。對(duì)于 Java 程序員來說,了解繼承的局限性以及針對(duì)傳統(tǒng)多重繼承問題的內(nèi)置 Java 解決方法同樣重要。
學(xué)習(xí)如何在Java中放置接口以重新創(chuàng)建多重繼承的效果將提高您的效率和可雇用性。