2012-08-10 6 views
6

抽象クラスを使用しています。すべてのサブクラスには、実装に基づいて定数を定義する必要があります。主にクラス実装に関するメタデータです。サブクラスでabstract javaクラスに定数を含めるようにサブクラスを強制する

protected static final String OBJECT_NAME; 
protected static final String OBJECT_DEF; 

そして:スーパーで

protected static final String OBJECT_NAME = "awesome class"; 
protected static final String OBJECT_DEF = "an awesome class that is also great"; 

は、定数を宣言するために、クラスの実装を強制する方法はありますか?

+1

潜在的に異なる値を持つ定数が定数ではないことに注目する価値はあるでしょう!だから、ピーターズの答えに行く。 – TedTrippin

答えて

7

サブクラスに、そのクラスの定数となるメソッドを定義させることができます。

protected abstract String objectName(); 
protected abstract String objectDef(); 

注:サブクラスのサブクラスがある場合は、これらのメソッドをオーバーライドするのが「忘れられる」可能性があります。

+0

はこれを示そうとしていた;) –

+2

あなたが得ることができる最高。 O.P.は彼がやりたいことを正確に行うことができないので、これは確かに最良のアプローチです。 –

+0

ありがとう!これを考えなかった(明らかに)。静的クラスのサブサブ実装がこれらのメソッドを実装することを保証する方法はありませんか? –

0

番号できません。

具体的な値を割り当てずに抽象スーパークラスで定数を宣言することさえできません。それ以外の場合は、エラーが発生します。宣言中またはクラスコンストラクターで、最終フィールドを初期化する必要があります。

変数を初期化する抽象メソッドを宣言できます(ただし、これは難読化されます)。このように:

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

しかし、この場合、変数とメソッドは静的であってはいけません。静的メソッドを抽象的に定義することはできません(look here for explanation)。

また、Peter Lawreyが提案した変数の代わりにメソッドを直接使用することもできます。これはより読みやすくなります。

0

これはうまくいかないでしょう。

private static final String OBJECT_NAME = "awesome class"; 
private static final String OBJECT_DEF = "bla"; 

protected String objectName(){ 
    return OBJECT_NAME; 
} 

protected String objectDef(){ 
    return OBJECT_DEF; 
} 

方法がないstaticですが、私はこれは、あなたが欲しいものを得ることができる最も近いと思う:

protected abstract String objectName(); 
protected abstract String objectDef(); 

サブクラスに:私は、抽象関数としてこれらを定義します。

Inreface HasObjectNameAndDef { 
    public String getObjectName(); 
    public String getObjectDef(); 
} 

と実際のクラスがインターフェイスを実装する必要があり:あなたはスーパークラスのための適切なデフォルト値を持っていないよう

1

は、同様にインタフェースのために行くかもしれません。あなたは簡単にテストを受けることができます。

-1

私はあなたが言っていることを知っています。例えば

私は、残念ながら

public interface ExecutableList<T extends ExecutableList<T,E>,E> //This is type parameter 
    extends List<E>,            //self referencing. Trust 
      Comparable<E>,          //me, it has its uses. 
{ 
    /** This would declare a constant but leave it to sub-interfaces/classes to define it. */ 
    abstract String USER_FRIENDLY_NAME; 

    //Define the rest of your interface 

} 

USER_FRIENDLY_NAME呼ばContantをStringフィールドを(私はExecutableListを呼び出しています)を持つインタフェースを持つようにしたい、これがJavaでできません。 Javaインタフェースでフィールドを宣言すると、修飾子public,static、およびfinalが含まれます。Javaプログラミング言語の将来の変更により、abstractが追加され、暗示的修飾子がpublic abstract static final String USER_FRIENDLY_NAME;になりましたが、これに対してルールを明確に定義することができますが、abstractという単語の使用は紛らわしく、abstractfinalは通常理解されています反対の意味を定義する。

私は将来のバージョンのJavaがこれを実装することを指摘しています。私はプライベートインターフェイスのメソッドがJava 9で追加されると聞いていますが(デフォルトのメソッド間で使用するため)、この言語に加えてまだ単語はありません。最初に検討しなければならない多くの後方互換性の問題があると思います。 Oracleの誰かがこれを読んでいる場合は、インターフェースで米国の宣言定数を使用して、そのクラス/インターフェースを定義してください!

あなたの唯一の選択肢は、インターフェイスまたは抽象クラスにString getUserFriendlyName();メソッドを定義することです。エレガントではなく、効果的ではないかもしれませんが、あなたは現在他に選択肢がありません。