I have a base class that captures some functionality common to two classes. In other words, I can create one base class and make these two classes subclasses of that base cl
Inheritance is not the only way to re-use common functionality. Containment may be preferable in the general case. Consider the following solution in which class A and B are the singletons, and the common functionality is in class AB, but instead of extending AB, both A and B use an instance of AB which is a singleton itself.
class AB { //common functionality of A and B
//singleton pattern here
//common data and functionality here
}
class A {
private AB ab = AB.getInstance();
//singleton pattern here
//unique functionality and data of A
//to use any of the functionality in AB delegate to member ab
}
class B is similar to A.
in this solution there is a single instance of every data and functionality of both A and B (and AB)
Note that if clients of A and B need to access the common public methods in AB, then AB, A and B should implement an interface of those public methods, and A and B implementation should delegate the call to ab.
The solution proposed by Ernest below, may be a shortcut in some situations, but in general is a wrong solution.
To explain why Ernest's solution may be wrong, let's describe that solution in a different way. Suppose i have a singleton class A and i discover that i need to write another singleton class B, but i need some of the functionality of A in B. So i factor out the common data and functionality of A into an abstract class AB and make both A and B extend AB. The reason why it's wrong, in general, is because this solution takes a subset of the data and functionality which is supposed to exist only once, and places it in a sub-class (AB), effectively and potentially duplicating it in every sub-class that will be created. Now, after getting an instance of A and an instance of B, you have two instances of the subset data and functionality in AB.
If for example, the common functionality placed in the base class writes some initial data to the file named "myData", then both of your singletons will execute this code even though it was only meant to be executed once, and when the later executes it it will wipe out the file created by the former.
Therefore, in general, the solution described here does not use inheritance, and ensures that a singleton encapsulates the common functionality as well as the singleton classes that use it.