簡體   English   中英

Java:如果A擴展了B並且B擴展了Object,那是多重繼承

[英]Java : If A extends B and B extends Object, is that multiple inheritance

我剛剛接受采訪,有人問我一個問題。

采訪者 -Java是否支持多重繼承?

-不

采訪者 -Java中的每個類都擴展了類Object(類Object除外),如果我們從外部擴展了一個類,例如

Class A extends B{
  // some code here
}

那么您可以說A類擴展了B類和Object類,這意味着它是多重繼承。 那么,怎么說Java不支持多重繼承呢?

-實際上,類B擴展了類Object,因此,當您在類A中擴展類B時,類A間接擴展了類Object。 這是多級繼承,而不是多繼承。

但是我的回答使他不滿意。

我的答案正確嗎? 還是我在哪里錯? 內部實際發生了什么?

我的答案是正確的嗎?

是的,大多數情況下,當然也可以根據您所描述的情況。 這不是多重繼承:

對象^-ClassA ^-ClassB

就是您所說的,具有多個級別的單一繼承。

這是多重繼承:從兩個或多個彼此沒有任何“ is”關系的鹼基繼承; 將從不相關的行或先前分歧的行繼承而來(在Java中,由於Object始終是基礎,因此它將是后者):

對象^-ClassA,對象^-ClassB,ClassA ^-ClassC,ClassB ^-ClassC

(圖片來源:“://”模式下的http://yuml.me

內部實際上會發生什么?

就像您說的那樣:有多個級別。 當編譯器解析實例上的成員時:

obj.member

...它看起來是因為obj的類型(在這種情況下是一個類,例如ClassB )是否具有member ,這是因為它直接提供了它,還是通過繼承了它。 在運行時,JVM使用對象實際擁有的member


我上面說“主要”的原因是Java具有接口,而從Java 8開始,它在接口上具有“默認方法”。 這使事情有些復雜,但是在描述訪調員對ObjectClassAClassB描述時,有關級別的答案是正確的。

在Java中,接口始終使某種東西具有兩種不同類型的“是”關系成為可能:它繼承自一個類類型,並且實現了幾種接口類型中的任何一種。 沒有默認方法的接口實際上不是多重繼承的(類必須提供實現),但是它們確實使類從不相關的類型樹中具有多個“是”關系成為可能。 (我不是學術人員,學術人員可能會爭辯說他們以學術方式提供多重繼承。)

使用Java 8,接口可以提供它們定義的方法的默認實現,即使在實際水平上,這也確實使界限模糊了。 讓我們更深入地看一下:

說我們有ClassA

class ClassA {
    void doSomething() {
        // Code here
    }
}

Interface1

interface Interface1 {
    default void doSomethingElse() { // Requires Java 8
        // Code here
    }
}

最后是ClassB

class ClassB extends ClassA implements Interface1 {
}

ClassBClassA繼承了doSomething的實現。 但是它Interface1獲得doSomethingElse的“默認”版本。 我們沒有在ClassB實現它,但是ClassB不是抽象的:它確實具有doSomethingElse 它從接口獲取它。 我用這個詞“被”,而不是“繼承”有,但像繼承的默認方法,這看起來很多

這基本上是多重繼承的“輕度”(如“輕度啤酒”中一樣)。 它通過真正的多重繼承來解決棘手的問題,例如:

  • super類型應該是什么? (Java 8的答案: ClassA
  • 您以什么順序運行構造函數? (Java 8的答案:單譜系構造函數鏈接,接口沒有構造函數。)
  • 您是否運行了多次繼承的構造函數? (Java 8的答案:您不能多次繼承構造函數,接口沒有它們。)
  • 如果您繼承具有相同簽名的多個方法會怎樣? (Java 8的回答:如果其中之一來自基類,那就是使用的那個;基類的實現可以覆蓋多個接口的默認方法。如果您在編譯時具有來自不同接口的具有相同簽名的多個默認方法,如果在不重新編譯類的情況下更改了接口,並且在運行時出現這種情況,則是運行時IncompatibleClassChangeError異常,列出了沖突的默認方法。)

你是對的

首先,對象類是包括用戶定義類在內的每個類的上級/基類/父類。

因此,即使我們沒有明確提及,默認情況下,用戶定義的類也會擴展Object類。

就像是

class A 
class B extends A

 but compiler read it as 
class A extends Object
class B extends A

證明了

有關更多詳細信息,請參見此Java文檔以進行繼承。

我的答案是正確的嗎?

絕對正確地說這是多級繼承,而不是多重繼承。

只有層次結構的Object ,所有類都不會單獨擴展Object。

反面試官:

如果所有類都擴展Object ,則將在A a = new A();上調用Object構造函數多少次A a = new A();

答案只有一次,這將是層次結構的根源。

是的,您是正確的...正如許多其他人指出的那樣。 我只是想說,面試不僅涉及技術知識,還涉及堅持不懈。 一些面試官會問您問題的答案,不是因為他們想知道您是否對自己的信念有把握,而是要測試您如何教別人,以及如何處理權威人物。

首先,如果你不能教別人,那么你就不能成為導師。 如今,聘請可以指導初級開發人員的人員至關重要……因為這樣做在經濟上很有意義。

第二點,因為他們不希望您的老板只是要求您更改技術方面。 如果老板因為您占用太多空間而要求您從數據庫中刪除所有索引,您會這樣做嗎? 您是否會說服老板? 怎么樣?

Does java support multiple inheritance?

是的,但不是接口的類。

該類和接口可以實現許多接口,但只能擴展一個類

您的回答是正確的!

class Object //for illustration purpose
{
}

class B
{
}

class A extends B
{
}

創建類A的對象時,會發生構造函數鏈接 即,類A的構造函數隱式調用super() ,因此,類B的構造函數被調用,然后隱式調用其超類,即Object類。

在Java中,一個類僅擴展一個類,因為該類的構造函數僅調用一個超類構造函數。 對於接口,這是不正確的,因為它們沒有構造函數。

同樣,當創建了類A的對象並假定您已經定義了類A和B的構造函數時,則首先執行類B的構造函數,然后再執行類A的構造函數。

您的答案是正確的,因為Java不支持從類進行多重繼承。 Java支持從接口的多重繼承,並且沒有任何其他繼承。 但是您可以使用類的組合,但這是另一回事了。

您的回答完全正確。 您可以從Java中的Object類解釋多級繼承支持的術語

真是愚蠢的問題。

當然,Java不支持多重繼承,接口也不被繼承。

繼承僅通過“擴展”發生,而不通過“實現”發生。 當您定義一個類實現多個接口時,並不是說它會是這些接口的擴展,但是它具有相同的行為,並且行為(至少在Java中是這樣)沒有定義繼承。

為了使Java支持多重繼承,它需要支持類似

public class MI extends Object, MyOtherClass

哪個Java不能。

好吧,也許我不會因為打電話給面試官的問題而愚蠢:)

您的答案是絕對正確的。

提出這些類型的問題只是為了檢查候選人在概念上是否強大。

這個問題最簡單,最准確的答案是:

類可以派生自類,這些類派生自類,這些類派生自類,等等,最終派生自最頂層的類Object。這樣的類被認為是繼承鏈中所有類的后代。反對。

請參考此鏈接https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

您給出的答案是正確的。 面試官錯了:

內部流程

if suppose Class A Doesn't extends any other class 
then ---> Class B extends java.lang.Object 
then ---> Class A extends B
then class A also inherited the property of java 'Object' class...

因此,Java不支持多重繼承。

如果要驗證此過程,只需為類A生成“ javadoc”並驗證結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM