web-dev-qa-db-ja.com

インターフェースのフィールド

Javaには基本的な質問がありますが、OOPには一般的な質問です。インターフェイスでフィールドを設定できるのはなぜですか?それはインターフェースがするはずのこととは逆に実行されないのですか?

私がそれを理解した方法、インターフェイスは、英語では形容詞になります。したがって、クラスがRunnableおよびSerializableインターフェースを実装している場合、クラスがRunnableおよびSeriablizableの条件を満たすことをユーザーに保証します。ただし、これは、インターフェイスが「ステートレス」であることを意味しますが、Javaのフィールドを持つことは許可されます...

何か不足していますか?

46
Sal

インターフェイスのすべてのフィールドはpublic static final、つまり定数です。

通常、このようなインターフェイスは避けることをお勧めしますが、メソッドを持たず、定数値のリストを含めるためだけに使用されるインターフェイスを見つけることができます。

55
Andrew Logvinov

まず、OOPパラダイムJavaでのOOP実装には違いがあるため、同じ単語は少し異なることを意味する場合があります。

OOPでは、パラダイムインターフェイスは、オブジェクトでできること(またはオブジェクトでできること)です。どのオブジェクトも複数のインターフェースを持つことができるため、異なる役割を果たします。たとえば、誰かがプログラマーとして働いてプログラムを作成することはできますが、同時に彼は夫であり父であるため、家族に代金を支払い、子供の世話をすることができます。ここで、「プログラマ」、「夫」、「父」はインターフェースであり、人はそれらを実装するオブジェクトです。インターフェイスは、オブジェクトを実装するための特定の機能(フィールド)の存在を意味するのではなく、このオブジェクトが実行できるアクションのみを意味することに注意してください。

Javaは多かれ少なかれこの考えに従いますが、どのようなパラダイム実装にも独自の機能があります。 Javaでは、メソッド、つまり実装オブジェクトが実行できるアクションを記述することができますが、実装の詳細はできないため、オブジェクトフィールドやプライベートメソッドについては何も記述できません。

しかし、定数public final staticフィールド)はどうでしょうか?それらは実装またはインターフェースの一部ですか?両方の可能性があります。例えば。インターフェース「プログラマー」は、定数「WORK_HOURS」を「8」に設定できます。したがって、Javaを使用すると、インターフェイスで定数を記述することもできます。

Javaは良いOOPデザインを作成するのに役立ちますが、それを強く要求するわけではないことに注意してください。特に、オブジェクトのすべてのパブリックメソッドがインターフェイスにも存在する必要はありません。たとえば、ゲッターメソッドとセッターメソッドは通常パブリックですが、実際にはインターフェイスではなく、実装の一部であるため、インターフェイスに含めないことは価値があります。

(ここで説明したほとんどのことはJavaのような主流のOOPについてですが、プロトタイプベースのもの、特にJavaScriptで実装されたものなど、他の種類のOOPもあります。

20
ffriend

そのインターフェイスが定数を参照している場合はどうなりますか?インターフェースで宣言するのは自然ではないでしょうか?

interface IdFinder {
    Serializable UNSAVED = new Serializable() {};

    /** @returns the given entity's persistent identity, 
                 or {@link UNSAVED} if it hasn't been saved yet, 
                 or null if o is a value object that hasn't a 
                 persistent identity of its own.
     */
    Serializable getId(Object o);
}
4
meriton

はい、インターフェイスに定数フィールドを設定できますが、「インターフェイスが行うべきことに反しているように見える」と言うのは正しいことです。同じ定数を持つインターフェイスを実装するすべてのクラスが必要なのはなぜですか?それらを使用するクラスに単純に配置するか、どうにかしてそれらをエクスポートする必要がある場合は、次のような別のクラスにそれらを使用してください。

public class Constants {
    private Constants() { }

    public static final int ZERO = 0;
    public static final int SOME_COMPLEX_NUM = 2124132L;
    ...
}

何らかの意味を持つ定数フィールドのセットを表す必要がある場合は、列挙型もあります。インターフェイスに定数が実際に必要な「ユースケース」は見当たりません。しかし、間違っている可能性があります:)

2
jlemos