web-dev-qa-db-ja.com

Java:AがBを拡張し、Bがオブジェクトを拡張する場合、その多重継承は

面接を受けたところ、質問されました。

インタビュアー-Javaは多重継承をサポートしていますか?

Me-いいえ

インタビュアー-Javaの各クラスは、クラスオブジェクト(クラスオブジェクトを除く)を拡張します。

Class A extends B{
  // some code here
}

クラスAはクラスBとクラスオブジェクトを拡張すると言うことができます。つまり、それは多重継承です。 Javaは多重継承をサポートしていません)

Me-実際にはクラスBがクラスオブジェクトを拡張するため、クラスAでクラスBを拡張すると、クラスAがクラスオブジェクトを間接的に拡張します。これは多重レベルの継承であり、多重継承ではありません。

しかし、私の答えは彼を満足させませんでした。

私の答えは正しいですか?または私はどこが間違っていますか?内部で実際に何が起こりますか?

31
Ankit Sharma

私の答えは正しいですか?

はい、ほとんど、そして確かにあなたが説明する文脈で。これは多重継承ではありません:

Object ^- ClassA ^- ClassB

それはあなたが言ったことです、複数のレベルを持つ単一の継承。

これは多重継承です。互いに「is a」関係を持たない2つ以上のベースから継承します。それは無関係な行、または以前に分岐した行から継承されます(Javaでは、Objectは常にベースであるため、後者です):

Object ^- ClassA, Object ^- ClassB, ClassA ^- ClassC, ClassB ^- ClassC

(画像クレジット: http://yuml.me 「だらしない」モード)

内部的に実際に何が起こりますか?

ちょうどあなたが言ったこと:複数のレベルがあります。コンパイラーがインスタンスのメンバーを解決している場合:

obj.member

...obj(この場合はクラス、たとえばClassB)のタイプがmemberを持っているかどうかを調べます。継承を通じてそれを持っています。実行時に、JVMはオブジェクトが実際に持っているmemberを使用します。


上記の「ほぼ」と言った理由は、Javaにインターフェースがあり、Java 8以降、インターフェースに「デフォルトのメソッド」があるためです。これにより、少しですが、レベルについてのあなたの答えは、インタビュアーがObjectClassA、およびClassBについて言っている説明の文脈では正しいです。

インターフェースは常に、Javaで何かが2つの異なるタイプとの「is a」関係を持つことを可能にしてきました。それが継承するクラスタイプと、いくつかのインターフェースタイプのいずれかimplements。デフォルトのメソッドのないインターフェースは、実用的な方法では多重継承ではありません(クラスは実装を提供する必要があります)が、クラスが無関係の型ツリーから複数の「is a」関係を持つことを可能にしました。 (私は学者ではありません。学者は学問的な方法で複数の継承を提供していると主張する可能性があります。)

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 {
}

ClassBdoSomethingからClassAの実装を継承します。しかし、alsoは、doSomethingElseの「デフォルト」バージョンをInterface1から取得します。 ClassBには実装していませんが、ClassBは抽象的ではありません。実際にはdoSomethingElseがあります。 インターフェースから取得します。 「継承」ではなく「取得」という単語を使用しましたが、これはデフォルトのメソッドを継承するようにlotのように見えます。

これは基本的に複数継承の「ライト」です(「ライトビール」のように)。次のように、真の多重継承に関する厄介な問題を回避します。

  • superのタイプはどうあるべきですか? (Java 8の答え:ClassA
  • コンストラクタはどの順序で実行しますか? (Java 8の答え:単一系統のコンストラクタチェーン、インターフェイスにはコンストラクタがありません。)
  • 継承するコンストラクターを複数回実行しますか? (Java 8の答え:コンストラクターを複数回継承することはできません。インターフェースにはコンストラクターがありません。)
  • 同じシグネチャを持つ複数のメソッドを継承するとどうなりますか? (Java 8の答え:それらの1つが基本クラスのものである場合、それが使用されます。基本クラスの実装は、複数のインターフェイスのデフォルトメソッドをオーバーライドできます。コンパイル時に異なるインターフェイスからの同じシグネチャを持つ複数のデフォルトメソッドがある場合時間、それはコンパイル時エラーです。クラスが再コンパイルされずにインターフェースが変更され、実行時に状況が発生した場合、それはランタイムIncompatibleClassChangeError例外であり、競合するデフォルトメソッドがリストされます。
39
T.J. Crowder

あなたは正しいです

まず、オブジェクトクラスは、ユーザー定義クラスを含むすべてのクラスのスーパー/ベース/親クラスです。

したがって、明示的に言及していなくても、ユーザー定義クラスはデフォルトでObjectクラスを拡張します。

そのような

class A 
class B extends A

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

証明した

詳細については、これを確認してください 継承に関するJavaドキュメント

7
MSR

私の答えは正しいですか?

あなたはそれが多重継承ではなく多重レベル継承であると言っていることで絶対に正しいです。

階層のrootのみがObjectであり、すべてのクラスは個別にはありません拡張オブジェクト。

インタビュアーへのカウンター:

すべてのクラスがObjectを拡張する場合、ObjectのコンストラクターがA a = new A();で呼び出される回数

答えは一度だけで、それは階層のルートに当てはまります。

5
Narendra Pathai

はい、あなたは正しいです...他の多くの人が指摘したように。インタビューは、技術的な知識だけでなく、銃へのこだわりについても言えると言いたかっただけです。一部の面接担当者は、自分の信念が確かであるかどうかを知りたいだけでなく、他の人にどの程度上手に教えることができるか、そして権威ある人物をどの程度うまく処理できるかをテストするために、あなたの答えに質問します。

第一に、他の人に教えることができない場合、メンターになることはできません。今日では、ジュニア開発者をコーチできる人を雇うことが重要です。経済的に意味があるからです。

2つ目のポイントについては、上司から依頼されたからといって技術的な側面を変えてほしくないからです。上司からスペースが多すぎるためにデータベースからすべてのインデックスを削除するように依頼された場合、削除しますか?そうでなければ上司を説得してみませんか?どうやって?

3
Does Java support multiple inheritance?

インターフェースにはありますが、クラスにはありません。

クラスとインターフェースは多くのインターフェースを実装できますが、拡張するクラスは1つだけです

2
mohamed sulibi

正解です!

_class Object //for illustration purpose
{
}

class B
{
}

class A extends B
{
}
_

クラスAのオブジェクトを作成すると、コンストラクタチェーンが発生します。つまり、クラスAのコンストラクターがsuper()を暗黙的に呼び出すため、クラスBのコンストラクターが呼び出され、そのスーパークラスがObjectクラスである暗黙的に呼び出されます。

Javaでは、クラスのコンストラクタは1つのスーパークラスコンストラクタのみを呼び出すため、クラスは単一のクラスのみを拡張します。インターフェースがない場合、コンストラクターがないため、これは当てはまりません。

また、クラスAのオブジェクトが作成され、クラスAとBの両方のコンストラクターが定義されていると想定すると、クラスBのコンストラクターが最初に実行され、次にクラスAのコンストラクターが実行されます。

2
Santosh Pavate

馬鹿げた質問です。

もちろんJavaは多重継承をサポートしておらず、インターフェースは継承されません。

継承は「拡張」を介してのみ発生し、「実装」を介しては発生しません。クラスが複数のインターフェースを実装することを定義するとき、それらがそれらのインターフェースの拡張になるとは言わないが、それは同じ振る舞いをし、振る舞い(少なくともJavaでは)は継承を定義しない。

Javaで多重継承をサポートするには、次のようなものをサポートする必要があります。

public class MI extends Object, MyOtherClass

Javaできません。

まあ、多分私はインタビュアーの質問ばかを呼び出すための仕事を得られないでしょう:)

1
Cindy Langdon

Javaはクラスからの多重継承をサポートしていません。Javaはインターフェースからの多重継承をサポートしており、他の継承はありません。クラスの構成を使用できますが、それは別の話です。

1
FruitDealer

あなたの答えは完全に大丈夫です。 JavaのObjectクラスからのマルチレベル継承サポートの観点から説明できます

あなたの答えは完全に正しいです。

これらの種類の質問は、候補者が概念的に強いかどうかを確認するためだけに尋ねられました。

さて、この質問に対する最も単純で正確な答えはここにあります:

クラスは、クラスから派生したクラスから派生したクラスから派生でき、最終的には最上位のクラスであるオブジェクトから派生します。このようなクラスは、 Objectに戻る継承チェーンのすべてのクラス。 "

このリンクを参照してください https://docs.Oracle.com/javase/tutorial/Java/IandI/subclasses.html

0
rags147

あなたが出した答えは正しいです。インタビュアーは間違っていました:

内部プロセス

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」を生成して結果を確認するだけです。

0