14

私の質問は、すでに実装されているクラスを拡張することによって暗黙的に実装されているインターフェイスが、クラスによって明示的に実装されるべきである場合、クラスがそのインターフェイスの契約を満たしているという事実を宣伝したい場合です。

たとえば、クラスを書きたい場合、それは interface の規約を満たしますjava.util.Listjava.util.AbstractListこれを実装して、既に interface を実装しているclass を拡張しますList。リストを実装することを明示的に宣言しますか?

public class MyList extends AbstractList implements List

それとも、暗黙の方法を使用して入力を節約しますか?

public class MyList extends AbstractList

どちらがより良いスタイルと見なされますか? どちらかの方法を優先する理由は何ですか? 方法 1 と方法 2 のどちらを優先しますか?

4

12 に答える 12

13

冗長性を回避します。方法 2 を使用します。

オーバーライドには @Override を使用します。

于 2008-12-12T13:47:27.900 に答える
9

それは「スタイル」の問題ではありません。List を既に実装している AbstractList を拡張する場合は、明示的に List を実装する必要はありません。

タイピングを節約するだけの問題ではありません。追加の「implements List」は冗長であるため、誰かがなぜそこにあるのかを理解しようとするのに時間がかかるかもしれません。あなたは本質的に、すでに言語の一部である保証を書いています。

于 2008-12-12T13:48:31.050 に答える
4

ずいぶん前にブログで同じ質問をしました。他の人の考えに興味がある場合は、そこにも長い議論があります. 興味深いことに、両方の戦略が JDK 内で採用されています。

最終的に、これに関する厳格なルールは意味をなさないと判断しました。何を伝えたいかについては、最善の判断を下す方がよいでしょう。

于 2008-12-13T04:07:09.913 に答える
3

クラスのユーザーが Class.getInterfaces() を介して実装されたインターフェイスのリストを取得できるようにする場合は、クラスの実装リストにすべてのインターフェイスを記載する必要があります。Class.getInterfaces() は、スーパー クラスによって実装されたインターフェイスを返しません。次のプログラムは、1 を出力してから 0 を出力します。

import java.io.Serializable;

class Test implements Serializable {
    class Inner extends Test {
    }

    public static void main(String[] argv) throws Exception {
        System.out.println(Test.class.getInterfaces().length);
        System.out.println(Inner.class.getInterfaces().length);
    }
}
于 2009-02-12T00:25:36.437 に答える
1

他のコメンターは、冗長性を避けるべきだと言っていますが、私は彼らに同意します。

一般的な質問に答えるために、両方を述べるために私が考えることができる唯一のケースは、AbstractFrotzer を拡張して Frobner を実装した場合、AbstractFrotzer が Frobner を実装した場合ですが、将来はそうではないかもしれないと信じる理由がありました。AbstractFrotzer が真に抽象的である場合、Frobner のすべてのメソッド自体を実装していない可能性さえあります。これは、あなたのクラスや、あなたのクラスが Frobner であることに依存している他のコードを変更しなくても、誰かが AbstractFrotzer のコントラクトを変更できる可能性があることを意味します。ただし、これは非常にまれな状況であると考えています。それが発生し、クラスが AbstractFrotzer を拡張しただけの場合でも、迅速なセマンティック チェックを行い、必要に応じて、implements 句を次の場所に追加するのは十分に簡単です。その点。

于 2008-12-12T15:43:25.047 に答える
1

サブクラスにインターフェイスを実装するのは冗長ですが、実装することをお勧めします。誰かが実装されたインターフェースをスーパークラスから削除する可能性があるためです。

于 2014-09-30T14:53:50.670 に答える
1

私は通常、オプション 2 に固執しますが、オプション 1 が適用される場合には、実際にはオプション 1 が適切であると主張します。

コードの使いやすさとわかりやすさは重要です。私たちが自問しなければならない問題は、このクラスへの参照を使用または参照している開発者が、このクラスがそのインターフェイスを実装していること (したがって本質的にサブタイプであること) を直感的に理解できるかどうかです。

適切に作成された典型的なクラスでは、クラスの名前によって、それがインターフェースを実装していることを明確にする必要があります。インターフェイスを追加すると、単なる冗長になります。

ただし、クラス名が実装するインターフェイスを明確にしない場合、およびにおいにもかかわらず、これが現状であり、これがスタックする名前である場合は実装を追加してインターフェイスを明示的に示すことが理にかなっています. これは、将来誰かが階層を変更した場合にも役立ちます。これは、このような非直感的な継承で可能です。

于 2008-12-13T22:15:35.767 に答える
1

私はより逐語的に言うでしょう。あなたのコードを読む他の人に、クラスが実装するものを調べさせなければならないのはなぜですか? クラスの継承機能が明確になります。ただし、プロジェクト内のすべてのコードで一貫性を維持しようとします。1 か所だけで行うと混乱しますが、一貫して行うと冗長性が認識されます。

補足: Java には非常に多くのクラスがあり、それらすべてを知っているのは誰ですか? さらに、各クラスがどのクラスから実装されているかを誰が知っていますか? 数秒余分に入力すると、仲間の開発者は 1 ~ 2 分見栄えの良いクラスを節約できます。

于 2008-12-12T13:55:21.520 に答える
0

私はこれを以前に見たことがありますが、多くの人がすでに指摘しているように、技術的に正しくないと感じています. 明白であるべきだと思いますが、何らかの理由でそうでない場合は、インターフェースを明示的に再度実装するよりも、クラスのコメントを通じて継承を示す方が理にかなっていると思います。

基底クラスが複数のインターフェイスを実装している場合はどうなりますか? 次に、これらすべてのインターフェイスを明示的に実装し、継承チェーンを完全にバックアップしますか? 明らかにそうではないので、このアプローチの矛盾はそれ自体が間違っていることが証明されていると思います. 意図はさまざまな方法で伝えることができますが、これは最善の方法ではありません。

于 2009-02-11T21:35:49.713 に答える
0

原則として、オプション 1 ではなくオプション 2 を使用します。

オプション 1 は、ほとんどの場合、開発者やコードを保守する人に付加価値を提供しません。

誰かが本当に特定のクラスのすべてのルートを知りたい場合は、どの IDE でも簡単にそれを実行できるはずです。(Eclipse: Ctrl+Shift+G)

AbstractList が List を実装しないことにした場合はどうなりますか? これは、大部分の一般クラスでは発生しません。他のあまり明白でない (信頼性が低い) ものはどうですか? もちろん例外もあるかもしれませんが、ごくわずかです (<1% ?)

于 2008-12-13T22:09:37.790 に答える
0

AbstractList を拡張すると、MyList はすでに「タイプ」リストであるため、インターフェイスを明示的に開始 (または実装) する必要はありません。

于 2008-12-12T13:50:07.037 に答える