我想定义一个像这样的抽象方法:
public abstract class Saveable {
public Set<Field> getFieldSet();
...
}
无论对象的状态如何, getFields()
都应始终返回相同的输出。但是,我不能将其声明为静态方法,因为我希望它被覆盖。现在我正在实现一个扩展User
的类Saveable
,它有一些需要字段集的静态方法。显然,我无法得到它因为我没有物体。设计上的任何想法都可以让我用静态方法获取字段吗?
答案 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);
...
}
}