20

クラスが複数のインターフェースを実装できることは知っていますが、複数のクラスを拡張することは可能ですか?たとえばTransformGroup、クラスと作成したクラスの両方を拡張したいとします。これはJavaで可能ですか?両方のステートメントclass X extends TransformGroup extends Yclass X extends TransformGroup, Yエラーを受け取ります。そしてそれが不可能なのなら、なぜですか?TransformGroup拡張しますが、フィールドを継承し、オブジェクトが必要な場所に渡すことができるため、Group拡張することもできると思います。また、Javaのすべてのクラスと同様に、クラスを拡張します。では、なぜ複数のクラスで拡張できないのでしょうか。 NodeNodeNodeObject

TransformGroupの継承

それで、それが可能であるならば、それをする適切な方法は何ですか?そうでない場合は、なぜ、どのように問題を解決する必要がありますか?

4

11 に答える 11

51

Javaでは、多重継承は許可されていません。これは、主に循環依存を回避するために、設計上の決定として言語から除外されました。

シナリオ1:学習したとおり、Javaでは次のことはできません。

public class Dog extends Animal, Canine{

}

シナリオ2:ただし、次のことが可能です。

public class Canine extends Animal{

}

public class Dog extends Canine{

}

これら2つのアプローチの違いは、2番目のアプローチでは明確に定義された親またはsuperクラスがあり、最初のアプローチではsuperクラスがあいまいであるということです。

AnimalCanineメソッドの両方があるかどうかを検討してくださいdrink()。最初のシナリオでは、呼び出した場合にどの親メソッドが呼び出されDog.drink()ますか?2番目のシナリオでは、呼び出しによって、オーバーライドされていない限り、 classesメソッドDog.drink()が呼び出されることがわかっています。CaninedrinkDog

于 2013-02-28T10:00:28.550 に答える
4

いいえ、Javaでは不可能です(おそらくJava 8では利用可能になります)。ツリーで拡張する場合を除きます。例えば:

class A
class B extends A
class C extends B
于 2013-02-28T10:02:57.643 に答える
4

Javaでは、インターフェースの実装(クラス)に対してのみ多重継承は許可されていません。

interface A extends B, C

たとえば、 MouseInputListenerはMouseListenerとMouseMotionListenerを拡張します

そしてもちろん、クラスはいくつかのインターフェースを実装できます。

class X implements A, F
于 2013-02-28T10:14:09.683 に答える
3

クラスでは多重継承は不可能です。インターフェースの助けを借りてそれを達成できますが、クラスでは達成できません。これは、Java言語の設計によるものです。ジェームズ・ゴスリングのコメントを見てください。

1995年2月のJamesGoslingによると、Javaで多重継承がサポートされていない理由がわかります。

JAVAは、C ++のめったに使用されない、よく理解されていない、紛らわしい機能の多くを省略しています。これは主に、演算子のオーバーロード(メソッドのオーバーロードはありますが)、多重継承、および広範な自動強制で構成されます。

于 2013-02-28T10:06:06.573 に答える
3

Javaには多重継承の概念はありません。複数のインターフェースのみを実装できます。

于 2013-02-28T10:01:13.160 に答える
3

多重継承

BとCが継承されたメソッドとそれら自身の実装をオーバーライドしていると仮定します。これで、Dは多重継承を使用してBとCの両方を継承します。Dはオーバーライドされたメソッドを継承する必要があります。問題は、どのオーバーライドされたメソッドが使用されるかということです。それはBまたはCからですか?ここにあいまいさがあります。このような状況を排除するために、Javaでは多重継承は使用されませんでした。

于 2016-01-05T18:30:28.923 に答える
2

javaは複数の継承をサポートできませんが、uはこの方法でこれを行うことができます

class X
{
}
class Y extends X
{
}
class Z extends Y{
}
于 2013-02-28T10:06:03.253 に答える
2

Javaは多重継承を提供しませんでした。
AがBを拡張すると言うとき、それはAがBを拡張し、Bがオブジェクトを拡張することを意味します。
AがB、オブジェクトを拡張するという意味ではありません。

class A extends Object
class B extends A

于 2013-02-28T10:03:53.830 に答える
1

与えられた答えのほとんどは、私たちが継承しようとしているすべてのクラスが私たちによって定義されていることを前提としているようです。

しかし、クラスの1つが私たちによって定義されていない場合、つまり、それらのクラスの1つが継承するものを変更できず、したがって受け入れられた回答を利用できない場合はどうなりますか?

答えは、少なくとも1つのクラスが定義されているかどうかによって異なります。Aつまり、継承したいクラスのリストの中に、A私たちが作成したクラスが存在します。

すでに受け入れられている答えに加えて、この多重継承問題の3つのインスタンスと、それぞれに対する可能な解決策を提案します。

継承タイプ1

Cクラスにクラスを拡張させたいとしましょうABここで、は別の場所で定義されているが、私たちによって定義されてBいるクラスですA。これでできることはA、インターフェースに変換することです。そうすれば、クラスはを拡張しながらC実装できます。AB

class A {}
class B {} // Some external class
class C {}

になる

interface A {}
class AImpl implements A {}
class B {} // Some external class
class C extends B implements A

継承タイプ2

ここで、継承するクラスが3つ以上あるとしましょう。同じ考えが当てはまります。ただし、1つを除くすべてのクラスを定義する必要があります。Aしたがって、クラスが次のクラスから継承するようにしたいとします。 B、、C...XここXで、は外部のクラス、つまり別の場所で定義されたクラスです。他のすべてのクラスを変換するという同じアイデアを適用しますが、最後のクラスをインターフェイスに変換すると、次のようになります。

interface B {}
class BImpl implements B {}
interface C {}
class CImpl implements C {}
...
class X {}
class A extends X implements B, C, ...

継承タイプ3

最後に、継承するクラスがたくさんあるのに、どれも自分で定義していない場合もあります。これは少し注意が必要ですが、委任を利用することで実行できます。委任により、クラスAは他のクラスのふりをすることBができますが、でA定義されたパブリックメソッドへの呼び出しはB、実際にはその型のオブジェクトへの呼び出しを委任しB、結果が返されます。これにより、クラスAは私が呼ぶものになりますFat class

これはどのように役立ちますか?

簡単です。使用する外部クラス内のパブリックメソッドと、作成する新しいクラス内のメソッドを指定するインターフェイスを作成してから、新しいクラスにそのインターフェイスを実装させます。それは紛らわしいように聞こえるかもしれませんので、もっとよく説明させてください。

最初に、次の外部クラス、、、B... 、、がCあり、新しいクラスがそれらすべてのクラスから継承するようにします。DXA

class B {
    public void foo() {}
}

class C {
    public void bar() {}
}

class D {
    public void fooFoo() {}
}

...

class X {
    public String fooBar() {}
}

A次に、以前はクラスAにあったパブリックメソッドと、上記のクラスのパブリックメソッドを公開するインターフェイスを作成します。

interface A {
    void doSomething(); // previously defined in A
    String fooBar(); // from class X
    void fooFoo(); // from class D
    void bar(); // from class C
    void foo(); // from class B
}

最後に、AImplインターフェースを実装するクラスを作成しますA

class AImpl implements A {
    // It needs instances of the other classes, so those should be
    // part of the constructor
    public AImpl(B b, C c, D d, X x) {}
    ... // define the methods within the interface
}

そして、あなたはそれを持っています!Aタイプのオブジェクトは、最初に使用した外部クラスの厳密な子孫ではなく、それらのクラスと同じメソッドを定義するインターフェイスを公開するため、これは一種の疑似継承です。

インターフェイスを定義するのではなく、使用したいメソッドを定義するクラスを作成しただけではないのはなぜかと疑問に思われるかもしれません。つまり、継承したいクラスのパブリックメソッドを含むクラスがなかったのはなぜですか?Aこれは、結合を減らすために行われます。A(クラスは大きく変化する傾向があるため)クラスに過度に依存する必要があるクラスは必要ありませんがA、インターフェイス内で指定されたpromiseに依存する必要がありますA

于 2017-04-11T06:37:14.100 に答える
0

Javaでは、複数のクラスを拡張することはできません。

CクラスがAクラスとBクラスを拡張していると仮定しましょう。次に、AクラスとBクラスに同じ名前のメソッドがあるとします(例:method1())。コードを考えてみましょう:

C obj1 = new C(); obj1.method1();-ここで、JVMはどのメソッドにアクセスする必要があるかを理解しません。AクラスとBクラスの両方にこのメソッドがあるためです。したがって、JVMをジレンマに陥らせているので、Javaから多重継承が削除されるのはそのためです。そして、前述のように、複数のクラスを実装すると、この問題が解決されます。

これがお役に立てば幸いです。

于 2013-10-19T05:53:01.693 に答える
-1

こんにちは、実際の仕事のように注意してください。

子供は2人の母親を持つことはできません

したがって、Javaでは、サブクラスに2つの親クラスを含めることはできません。

于 2016-10-26T07:00:40.773 に答える