抽象类中的静态方法

时间:2011-07-01 16:26:45

标签: java oop inheritance static

我想定义一个像这样的抽象方法:

public abstract class Saveable {
    public Set<Field> getFieldSet();
    ...
}
无论对象的状态如何,

getFields()都应始终返回相同的输出。但是,我不能将其声明为静态方法,因为我希望它被覆盖。现在我正在实现一个扩展User的类Saveable,它有一些需要字段集的静态方法。显然,我无法得到它因为我没有物体。设计上的任何想法都可以让我用静态方法获取字段吗?

6 个答案:

答案 0 :(得分:4)

通过将正确对象的实例传递给静态方法,然后在该对象上调用this,一种方法是“伪造”getFields引用。

另一种选择是将字段列表存储在类的静态字段中。您重写的getFields()实现可以返回它(或者最好是它的副本),并且您的静态方法可以直接访问它。

我的偏好是实现后一个选项,因为它不那么笨拙(因为你永远不需要新建一个无用的对象来传递给静态方法。)同样,它捕获了类的想法字段不依赖于给定的实例。

答案 1 :(得分:1)

不幸的是,继承的类不能覆盖静态方法,但可以通过声明具有相同签名的静态方法来隐藏它。

如果你的最终目的是在GetFields()类中的另一个继承方法中使用Saveable,这对你没有帮助,因为它总是会调用Saveable.getFields(),而不是静态方法你的扩展课程。

答案 2 :(得分:1)

您可以将当前方法保留为Savable中的非静态和抽象方法,并从非静态实现中返回静态Set。

public class User extends Savable {

    public static Set<AField> aSet = new HashSet<AField>();

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

答案 3 :(得分:0)

调用静态方法时,您将类的名称称为范围。

所以实际上没有覆盖的意义,你只是隐藏它。

此外,由于同样的原因,它不能被继承,因为它属于类类型,而不是类实例。

您可以做的最好的事情是在派生类中调用基类的静态方法,并使用相同的方法名称。

答案 4 :(得分:0)

扩展@dlev的答案,如何将字段存储在由每个类的唯一标识符键入的hashmap中。

如果您使用的是Spring,则可以在每个对象中注入一组字段。因此,只有参考文献才会重复。

答案 5 :(得分: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<Class<? extends Saveable>, Set<? extends Field>> map =
        new HashMap<Class<? extends Saveable>, 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);
    ...
}
}