Reputation: 31380
I have some classes that are used as Singletons. They share some basic functionality and extend the same ancestor from a library which in turn isn't normally used as a Singleton.
If I put the common functionality in a base class that inherits from the common ancestor, I get a class which makes no sense to instantiate, so I made it abstract. Also, because the classes are all used as Singletons, they should all have an init() and a getInstance() method, which are both static. All the constructors are of course non-public.
Now, since static
is an illegal modifier for abstract methods, the following doesn't work, although this would be exactly what I want:
class Base extends LibraryClass {
protected Base() {
// ... constructor
}
// ... common methods
// ILLEGAL!
public static abstract void init();
public static abstract <T extends Base>T getInstance();
}
class A extends Base {
private static A _INSTANCE;
private A() {
super();
}
public static void init() {
_INSTANCE = new A();
}
public static A getInstance() {
return _INSTANCE;
}
}
I could just leave out the illegal lines in the base class and be done with it. But how do I express that every child of Base must have these methods?
Upvotes: 11
Views: 8435
Reputation: 15788
A common way to deal with adding singleton semantics to a class for which it may be inconvenient to add the semantics correctly is to implement the singleton functionality in a wrapper class. For example:
public class UsefulThing {
}
public final class SingletonOfUsefulThing {
private static UsefulThing instance;
private SingletonOfUsefulThing() {}
public UsefulThing getInstance() {
if (instance == null) {
instance = new UsefulThing();
}
return instance;
}
}
This allows you to give some of the primary singleton benefits to a class without some of the consequences that implementing the singleton semantics in the class directly forces you to deal with and allows some room for changing the specific type of the class you're exposing as a singleton (via using a factory to create the instance, for example, instead of new
.
Upvotes: 3
Reputation: 62769
Why don't you go all the way and make your factory (in the base class) pass in a parameter indicating which sub-class you want it to return. There are lots of advantages to doing it that way, and few disadvantages.
The way you are trying to do it doesn't make a whole lot of sense since static methods don't deal with inheritance in quite the same way as normal methods.
Upvotes: 1
Reputation: 328614
This is not possible in Java. Existence of static
methods can't be enforced; neither by abstract
nor by using an interface
.
My solution was to use IoC in a way: I created a factory class for singletons. It would save the singletons in a map. The key would be the class. This way, I could say:
A singleton = Factory.create (A.class);
The major advantage of this design: I can create a Factory.replace()
method where test cases can override the singletons.
Upvotes: 14
Reputation: 31463
You can't express that child classes have specific static methods.
In fact there should be no need to do this as the static methods will only be called directly on the child classes (A.init()
and A.getInstance()
in your example) and never through a reference to the base class (i.e. static methods do not support polymorphism).
Upvotes: 2