好的,所以我知道你不能有一个抽象的静态方法,虽然我个人认为这是一个限制。我也知道重写静态方法是没用的,因为当我处理say MyList<T extends ObjectWithId>
并且我的对象有一个抽象类,其静态方法被覆盖在它的子类中时,T在运行时不存在{{1将调用静态方法而不是子类。
所以这就是我所拥有的:
ObjectWithId
其中class PersistentList<T extends ObjectWithId> implements List<T>{
}
是:
ObjectWithId
现在的问题是我的PersistentList意图存储在硬盘上,因此名称,实际上只存储它所拥有的对象的id。现在我想实现
abstract ObjectWithId{
public abstract long getId();
}
@Override
public T get(int index) {
}
的方法,我希望我的程序使用它为PersistentList
存储的id
并调用静态方法index
objectForId(long id)
的每个子类。它不能是实例方法,因为还没有实例,重点是使用ObjectWithId
从硬盘加载实例。那应该如何实施呢?一个选项是让id
在每个子类中实现构造函数ObjectWithId
,但T在运行时不存在,那么我将如何实例化它?我知道我可以在ObjectWithId(long id)
的构造函数中传递Class<T>
对象但我更喜欢构造函数没有任何参数,但我认为没有办法获得T的类而没有明确地传递它吗?
我希望这是一个更好的解释,对于我开始时提出的含糊不清的问题感到抱歉。
答案 0 :(得分:1)
虽然从静态方法开始似乎总是比较容易,但我发现,出于这个原因通常避免使用静态方法通常是有益的,并且默认情况下使用实例方法。
这样做的好处是可扩展性。除了允许继承和避免您提到的“限制”之外,它还提供了可扩展性 - 无需重新设计和稍后更改API。例如,“这个类完全符合我的需要,但我希望我只能改变这部分功能”。如果有静态方法调用其他静态方法,则没有好办法。如果所有方法都是非静态的 - 我可以子类化该类并仅覆盖所需功能的一部分。
静态方法的另一个(有些相关的)限制是它们不能用于实现接口。
总之,我更喜欢为“实用方法”保留静态方法,其中它们正在执行的功能非常明确,并且没有任何可行的未来理由可以为什么需要提供替代实现。< / p>
答案 1 :(得分:1)
在传递Class<T>
作为构造函数参数时,它并没有真正解决您的问题。然后,您可以访问该类,但是要访问该类上定义的静态方法,您必须使用泛型(除非其他人知道从Class对象调用类上定义的静态方法的方法)。
我将定义一个新的通用接口,它包含一个通用方法objectForID
,类似于
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
并调整PersistentList
的构造函数以将此ObjectRetriever
实例作为参数。然后可以使用此ObjectRetriever
根据其ID恢复对象。