我有一个超类,我想将一个名为getInstance()
的静态方法转发给所有子类。
在创建子类的实例时,我会在超类中注册该实例(可能使用哈希表,其中的键基于getClass()
)。然后,我希望使用前面提到的静态方法( getInstance
),其中超类方法将返回正确类型的实例。
例如,我有一个超类A,一个子类B扩展了A。我想编写一个静态方法A.getInstance()
;当从B (B.getInstance()
)调用时,我希望它返回我之前存储的B的实例。
这有点难以解释,但我将经常使用这个超类,并且我不希望在每个子类中都编写getInstance
方法。
我该如何着手做这样的事情呢?
编辑:我刚刚意识到我的问题可能会被误解为创建对象的新实例。我已经创建了实例,并且希望获得类的现有实例
发布于 2013-01-16 08:06:01
正如许多其他人在评论中指出的那样,使用静态方法不可能完成您想要做的事情。此外,您应该尽可能避免使用静态方法,因为它们可能会导致测试和维护的噩梦(*)。
您将您的方法命名为"getInstance",所以我猜您想要做的是工厂模式和单例模式的混合。下面是一些关于这些模式的入门信息:
单例:http://en.wikipedia.org/wiki/Singleton_pattern
工厂方法:http://en.wikipedia.org/wiki/Factory_method_pattern
抽象工厂:http://en.wikipedia.org/wiki/Abstract_factory
现在两者都不应该手工编码(*) -看看好的“依赖注入”(DI)容器,比如Google Guice或Spring。我不能百分之百确定你到底想要实现什么,但看起来DI容器会为你做到这一点。
编辑:这是对问题编辑的响应。您希望接收子类的缓存实例。在这种情况下,我仍然建议不要使用静态方法。您可以创建"BCache“类的单例实例(使用DI容器或手动编程),然后使用此缓存对象查找已注册的对象。使用Guice作为DI容器,它可能如下所示(警告,未测试):
@Singleton
public class BCache {
private Map<Class<? extends B>, B> cache = ...;
public <T> T getInstance(Class<? extends T> type) {
return (T) cache.get(type);
}
}
不过,我仍然认为使用DI容器完全摆脱缓存类是可能的。同样,这是使用Guice的未经测试的代码,但它可能如下所示:
@Singleton
public class A extends B {
public A() {
//I am not sure if you need to register in this case, because your
//DI container keeps track of the singleton instances.
super.register(this);
}
}
public class SomeClassUsingA {
@Inject private A a;
}
(*)注意“所有的概括都是错误的”,也就是说,在一些项目中它可能是有意义的,但在大多数项目中它不会。
发布于 2013-01-16 08:11:08
你不能用好的OOP方式用静态方法做你想做的事情。您可以使用反射或if .. else if
束来做一些事情。
但是,您应该使用一些定义良好的设计模式,如Abstract fectory或Factory method。这就是你应该走的路,就像有人说的“不要发明温水”。
发布于 2013-01-16 08:18:48
您始终可以将subClass实例分配给superClass引用。因此,您的超类的静态方法可以设置或获取subClass实例。但请确保在使用之前强制转换返回的实例。
public class A {
private static A a;
/**
* @param a the a to set
*/
public static void setA(A a) {
A.a = a;
}
/**
* @return the a
*/
public static A getA() {
return a;
}
public class B extends A {
private int index = 0;
/**
* @param index the index to set
*/
public void setIndex(int index) {
this.index = index;
}
/**
* @return the index
*/
public int getIndex() {
return index;
}
用法:
public static void main(String[] args) throws Exception {
B b = new B();
A.setA(b);
B c = (B) A.getA();
System.out.println(c.getIndex());
}
https://stackoverflow.com/questions/14353620
复制