我读到你不能在泛型类中声明静态变量/方法,我真的不知道如何解决我的问题或解决它,所以我请求你的指导。
我想要的是一个通用的"索引",我的所有核心类都将扩展它。我正在创建一个游戏引擎,一个例子是,我将有不同的游戏状态,它们都扩展了State
,而Nexus<State>
又扩展了。我想要静态头和尾的原因是,我可以保留所有游戏状态的链接列表,因为它们都是在创建时添加到该列表中的。
另一个例子是,我将有不同的游戏对象,它们都扩展了GameObject
,而Nexus<GameObject>
又扩展了。
这就是名为Nexus
:的索引
public abstract class Nexus<T>
{
private static T head = null;
private static T tail = null;
private T next = null;
private static int num = 0;
protected Nexus() { this.Add( (T)this ); }
public T Add( T obj )
{
((Nexus)obj).next = null;
if( num++ == 0 ) head = tail = obj;
else tail = ( tail.next = obj );
return obj;
}
}
如果有人有其他解决方案或变通办法,我会洗耳恭听!
Java泛型与C#泛型大不相同。有类型擦除,所以不能说Nexus<T>.aStaticPublicField
(就像C#中一样(。你只能说Nexus.aStaticPublicField
。没有办法知道泛型类型是什么(因为你没有实例(,所以你不能有一个类型为t的静态字段。
尝试这种方法:定义一个protected abstract
方法,子类实现该方法以返回其类的static
对象。
可能有一些逻辑问题等,但答案的基础在这里(即编译(:
编辑:现在委派给HeadAndTail
/** <T> A subclass of Nexus */
abstract class Nexus<T extends Nexus<T>> { // This syntax lets you confine T to a subclass of Nexus
private T next;
protected Nexus() {
this.add((T) this);
}
public T add(T obj) {
// Delegate to HeadAndTail
return getHeadAndTail().add(obj);
}
/** @return a static for the class */
protected abstract HeadAndTail<T> getHeadAndTail();
}
/** Bundled into one Object for simplicity of API */
class HeadAndTail<T extends Nexus<T>> {
T head = null;
T tail = null;
int num = 0;
public T add(T obj) {
obj.next = null;
if (num++ == 0)
head = tail = obj;
else
tail = tail.next = obj;
return obj;
}
}
class ConcreteNexus extends Nexus<ConcreteNexus> {
// This is the static object all instances will return from the method
private static HeadAndTail<ConcreteNexus> headAndTail = new HeadAndTail<ConcreteNexus>();
protected HeadAndTail<ConcreteNexus> getHeadAndTail() {
return headAndTail; // return the static
}
}
根据http://download.oracle.com/javase/tutorial/java/IandI/abstract.html
班级成员-抽象类可能具有静态字段和静态方法。您可以将这些静态成员与类引用一起使用,例如AbstractClass.staticMethod((,就像使用任何其他类一样。
但我自己还没有测试过
一组静态字段不是实现这一点的好方法。我不太理解您的要求,但似乎更好的方法是更改此类的构造函数的签名,以便传入全局索引对象。
也就是说,而不是这个:
protected Nexus() { this.Add( (T)this ); }
你可以这样做:
protected Nexus(GameStateIndex<T> index) { index.Add(this); }
这适当地分离了跟踪游戏状态和跟踪所有游戏状态的索引的职责。(参见"单一责任原则"。(它还明确指出,创建状态对象依赖于正确索引该状态。