web-dev-qa-db-ja.com

Javaインターフェースがインターフェースを拡張する理由

インターフェイスからインターフェイスをどのような状況で拡張するのでしょうか?なぜなら、例えば

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

同等ではないですか

interface A{
    public void method1();
}
interface B{
    public void method2();     
}
class C implements A, B{
    @Override public void method1(){}
    @Override public void method2(){}
}

背後にある重要な理由はありますか?

35
peter

重要な理由は、インターフェースが何をすべきかによって完全に異なります。

インターフェースVehicleとインターフェースDrivableがある場合、すべての車両が駆動可能であることは理にかなっています。インターフェイスの継承がなければ、あらゆる種類の車のクラスが必要になります

class ChevyVolt implements Vehicle, Drivable
class FordEscort implements Vehicle, Drivable
class ToyotaPrius implements Vehicle, Drivable

等々。

私が言ったように、すべての車両は運転可能なので、ただ持っている方が簡単です:

class ChevyVolt implements Vehicle
class FordEscort implements Vehicle
class ToyotaPrius implements Vehicle

次のように車両で:

interface Vehicle extends Drivable

そして、それについて考える必要はありません。

54
Spencer Ruport

はい、あります。それはどこか他の場所の継承のようなものです。 B is a Aの特殊化の場合、そのように記述する必要があります。 2番目のものは、クラスがたまたま2つのインターフェイスを実装し、それらの間に関係がないことを示しています。

最終結果の観点から、階層を処理する代わりに複数のインターフェイスを使用することができます(クラス階層で継承された動作を使用するのを避けることができるように)。ただし、これにより情報が散在し、ソフトウェアモデルの意図が大幅に難読化されるためです。

12
Matt Whipple

はい、1つの大きな違いがあります。

最初の例では、新しいインターフェイスBはAから拡張するように定義されているため、今後は、Bを実装するクラスanyクラスautomaticallyはAを実装します。基本的に、コンパイラに「これがAであることの意味、ここにBであることの意味、そしてby方法、すべてのBもAです!」それはあなたのようなことを言うことができます...

class C implements B {
    ... you implement all of the methods you need...
    ...blah...
    ...blah...
}
A myNewA = new C();

そしてそれはうまくいきます。

ただし、secondの例では、Bを宣言してAを拡張しないため、上記のコードは機能しません。 (2番目の種類の)CのインスタンスをAの参照に割り当てようとすると、have n't 「すべてのBは本当にAです」 (つまり、BCの間に関係はありません)

5
Bob Gilmore

Aを実装せずにBを実装したくない場合は、BをAに拡張できます。

例:

interface LivingThing{
public void eat();
}

interface Dog extends LivingThing{
public void Bark();
}

犬にならずに生き物になることは可能ですが、生き物にならずに犬になることはできません。それで、それがbarえることができるならば、それはまた食べることができます、しかし、反対は常に真実ではありません。

2
WVrock

あなたが言っていることは正しいですが、それは私たちの仕事を終わらせることだけではありません。要件が次のようなものである場合はどうでしょうか:

1)10個のインターフェースがあり、同時に設計されていないことを想像してください。例えばJava 7.のAutoCloseableインターフェイス。新しい自動クローズ機能が追加されました。Java 6。

2)マーカーインターフェイスであるインターフェイスCを設計し、特定のクラスBから派生したすべてのクラスにマークを付ける場合、最良の解決策は、Bを使用してCを拡張し、実装Cをどこにも配置しないことです。

さらに多くの理由があります。クラスと階層の全体像を見ると、自分で答えを得ることができます。

ダラムを助けて幸せ

1
dharam

コメントは1つだけです

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

a a = new C();を宣言した場合

method2()を呼び出すことはできません。クラスCのメソッドを実装しても、インターフェイスAはインターフェイスBの要素について何も知らないため

0
Moamen Adel

ここでの主な違いは、最初の例ではBがAであり、次にAであるということです。つまり、インターフェイスBはmethod1()とmethod2()を呼び出します。2番目の場合と同様に、AとBは別々です(インターフェイスBはmethod1()を終了しない)。クラスCはAとBを実装します。 ()およびmethod2()。これがお役に立てば幸いです!

0
Nick