抽象クラスの静的メソッド

inheritance java oop static
抽象クラスの静的メソッド

次のような抽象メソッドを定義したい:

public abstract class Saveable {
    public Set getFieldSet();
    ...
}

オブジェクトの状態に関係なく、 getFields()`は常に同じ出力を返します。 ただし、オーバーライドしたいので、これを静的メソッドとして宣言することはできません。 現在、 `Saveable`を拡張するクラス User`を実装しており、フィールドセットを必要とするいくつかの静的メソッドがあります。 明らかに、オブジェクトを持っていないので手に入れることができません。 静的メソッドでフィールドを取得できるようにする設計上のアイデアはありますか?

  3  2


ベストアンサー

1つのアプローチは、正しいオブジェクトのインスタンスを静的メソッドに渡し、そのオブジェクトで「getFields」を呼び出すことにより、「this」参照を「偽造」することです。

別のオプションは、クラスの静的フィールドにフィールドリストを格納することです。 オーバーライドされた `getFields()`実装はそれ(またはできればそのコピー)を返すことができ、静的メソッドは直接アクセスできます。

私の好みは、後者のオプションを実装することです。これは、あまり面倒ではないためです(静的メソッドに渡すために、そうでなければ役に立たないオブジェクトを新しくする必要がないためです)。また、クラスのフィールドがtは特定のインスタンスに依存します。

4


残念ながら、継承されたクラスは静的メソッドをオーバーライドすることはできませんが、同じシグネチャを持つ静的メソッドを宣言することでそれを隠すことができます。

最終的な目的が、 Saveable`クラスの別の継承メソッド内で GetFields() を使用することである場合、これは役に立ちません。拡張クラスの静的メソッドではなく、常に Saveable.getFields() `を呼び出すためです。 。

1


現在のメソッドをSavableで非静的かつ抽象のままにして、非静的実装から静的Setを返すことができます。

public class User extends Savable {

    public static Set aSet = new HashSet();

    @Override
    public Set<? extends Field> getFields() {
        return aSet;
    }
}

1


静的メソッドを呼び出すときは、スコープとしてクラスの名前を呼び出しています。

したがって、実際にオーバーライドする意味はありません。とにかくそれを隠すだけです。

また、同じ理由で、クラスインスタンスではなくクラスタイプに属するため、継承できません。

最善の方法は、派生クラスで基本クラスの静的メソッドを呼び出し、同じメソッド名を付けることです。

0


@dlevの答えを拡張して、クラスごとに一意の識別子でキーオフされたハッシュマップにフィールドを保存する方法について。

Springを使用している場合、すべてのオブジェクトに一連のフィールドを挿入できます。 したがって、参照のみが複製されます。

0


これが提案です、私は解決しました。 しかし、何らかの方法で派生クラス名に名前を付ける必要があります。これらのフィールドをロードするときは、とにかくメソッドを静的に宣言する以外に方法はありません。

public abstract class Saveable {
    public static Set<? extends Field> getFields(Class<? extends Saveable> clazz) {
        return FieldsProvider.get(clazz);
    }
}

public class FieldsProvider {
    private static final Map, Set<? extends Field>> map =
        new HashMap, Set<? extends Field>>();

public static void registerFields(Class<? extends Saveable> clazz, Collection<? extends Field> col) {
    Set<? extends Saveable> set = new HashSet<? extends Saveable>();
    set.addAll(col);
    map.put(clazz, set);
}

public static Set<? extends Field> getFieldSet(Class<? extends Saveable> clazz) {
    Set<? extends Field> set = map.get(clazz);
    if (set != null) {
        return set;
    }
    return Collections.emptySet();
}
}

public class User extends Saveable {
static {
    FieldsProvider.registerFields(User.class, new HashSet<? extends Field>... ;
}

static void someMethod() {
    Set<? extends Field> fieldsSet = getFields(User.class);
    ...
}
}

0


タイトルとURLをコピーしました