web-dev-qa-db-ja.com

複数のクラスJavaを拡張するクラス?

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

TransformGroupの継承

それで、それが可能であれば、それを行う適切な方法は何ですか?そうでない場合、問題を解決する理由と方法を教えてください。

20
Mihai Bujanca

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

Scenario1:学習したとおり、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番目のシナリオでは、Dog.drink()を呼び出すと、Canineがオーバーライドしない限り、drinkクラスDogメソッドを呼び出すことがわかります。

50
Kevin Bowersox

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

interface A extends B, C

例えば。 MouseInputListener MouseListenerおよびMouseMotionListenerを拡張

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

class X implements A, F
4
Puce

いいえ、Java(たぶんJava 8で利用可能になる)。

class A
class B extends A
class C extends B
4
András Tóth

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

3
Aashray

多重継承http://bit.ly/1Z62XjI

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

3
amitguptageek

クラスでは多重継承はできません。クラスではなくインターフェイスの助けを借りて達成できます。 Java language。James James Goslingのコメントをご覧ください。

1995年2月のジェームズゴスリングは、多重継承がJavaでサポートされていない理由を説明しています。

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

3
Rais Alam

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

class A extends Object
class B extends A

2
The Reader

Javaは多重継承をサポートできませんが、この方法でこれを行うことができます

class X
{
}
class Y extends X
{
}
class Z extends Y{
}
2
Biswajit

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

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

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

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

継承タイプ1

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

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を次のクラスBC、... 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型のオブジェクトへの呼び出しを委任し、結果が返されます。これにより、クラスAFat classと呼ばれるものになります

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

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

最初に、次の外部クラスBCD、...、Xがあり、新しいクラスAにこれらすべてのクラスを継承させます。

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がなかったのですか?これはreduce カップリングAを使用するクラスが、クラスAに過度に依存する必要はありません(クラスは大きく変化する傾向があるため)。むしろ、インターフェイスA内で指定されたプロミスに依存します。

1
smac89

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

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

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

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

0
Srekk