49

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

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

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

4

8 に答える 8

73

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

インターフェース 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

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

于 2012-11-18T03:23:31.230 に答える
14

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

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

于 2012-11-18T03:19:59.410 に答える
7

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

最初の例では、新しいインターフェイス B は A から拡張するように定義されているため、今後は、 B を実装するすべてのクラスが自動的にA を実装します。はBであることを意味し、ちなみにBはすべてAでもあります!」それはあなたが次のようなことを言うことができます...

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

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

しかし、2 番目の例では、B を宣言して A を拡張しないため、上記のコードは機能しません。(2 番目の種類の) C のインスタンスを A の参照に割り当てようとすると、「すべての B は実際には A である」とコンパイラに伝えていないため、エラーが発生します。B(つまり、 と の間に関係はありませんC)

于 2012-11-18T03:28:02.453 に答える
1

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

1) 同時に設計されていない 10 個のインターフェイスがあるとします。たとえば、Java 7 の AutoCloseable インターフェイスなどです。新しい自動クローズ機能が追加されましたが、Java 6 まではありませんでした。

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

さらに多くの理由があります。クラスと階層の全体像を見れば、答えは自分でわかるかもしれません。

ダーラムを喜んで助けます

于 2012-11-18T03:31:23.300 に答える
0

ここでの主な違いは、最初の例では B が A であり、次にいくつかであるということです。つまり、インターフェイス B が method1() と method2() を呼び出します。2 番目の例では、A と B は分離されており (インターフェイス B は method1() を締結しません)、クラス C は A と B を実装しています。どちらのインスタンスでも、クラス C は method1 をオーバーライドします。 () および method2()。これが役立つことを願っています!

于 2013-01-11T01:56:16.163 に答える