Reputation: 2169
Ok so I know that you can't have an abstract static method, although I see this as a limitation personally. I also know that overriding static methods is useless because when I am dealing with say MyList<T extends ObjectWithId>
and my object has an abstract class with a static method that gets overridden in it's subclasses, T doesn't exist at runtime so ObjectWithId
's static method would be called instead of the subclass.
So here is what I have:
class PersistentList<T extends ObjectWithId> implements List<T>{
}
where ObjectWithId
is:
abstract ObjectWithId{
public abstract long getId();
}
Now the issue is that my PersistentList is meant to be stored on hard disk, hence the name, and in reality will only store ids of objects it holds. Now when I want to implement the
@Override
public T get(int index) {
}
method of PersistentList
, what I want is for my program to use the id
it has stored for index
and call a static method objectForId(long id)
which would be implemented in each subclass of ObjectWithId
. It can't be a instance method because there is no instance yet, the point is to load the instance from the hard disk using the id
. So how should it be implemented? One option is to have ObjectWithId
have a constructor ObjectWithId(long id)
implemented in each subclass, but T doesn't exist at runtime so how would I instantiate it? I know I could pass Class<T>
object in the constructor of PersistentList
but I would prefer if the constructor did not have any arguments, but I don't think there is a way to get the class of T without explicitly passing it in right?
I hope this is a better explanation, sorry for the ambiguous question I started with.
Upvotes: 1
Views: 1946
Reputation: 36621
While passing the Class<T>
as a constructor argument, it does not really solves your problem. You then have access to the class, but to get access to the static method defined on the class you will have to use generics (unless somebody else knows a way to call a static method defined on a class from a Class object).
I would define a new generic interface which contains a generic method objectForID
, something like
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
and adjust the constructor of the PersistentList
to take such a ObjectRetriever
instance as parameter. This ObjectRetriever
can then be used to restore the objects based on their ID.
Upvotes: 1
Reputation: 28707
While it always seems easier to start out with static methods, I've found it to usually be beneficial to avoid static methods for just this reason, and to use instance methods by default.
The advantage to this is extensibility. Besides allowing for inheritance and avoiding the "limitations" you mentioned, it provides for extensibility - without needing to redesign things and change APIs later. For example, "this class does exactly what I need, but I wish I could change only this one portion of functionality". If there are static methods calling other static methods, there is no good way to do this. If all the methods are non-static - I can subclass that class and override only the portion of functionality required.
The other (somewhat-related) limitation to static methods is that they can't be used to implement interfaces.
In summary, I prefer to reserve static methods for "utility methods" where the function that they are performing is really clear-cut, and there isn't any feasible future reason why an alternative implementation would need to be provided.
Upvotes: 1