Wednesday, April 23, 2008

Private constructor

Colleague: Hey man, is it allowed to declare a private constructor (and no other public constructors)?
me: (immediately) Yes!

Colleague: Why would one do that?
me: To disallow other classes to instantiate that class

Colleague: But is that class good for anything if other classes cannot instantiate it?
me: Yeah, even if it is a private constructor you can instantiate that class within that class (i.e. inside its own method(s)) and other classes would use that method to access the instance of that class.

Colleague: But, then I don't see any use of making it private then.
me: When you make things private from rest of the world, you basically want to restrict/control the access of those private things. That is what you can achieve it here too. In this case, you want to control instantiation of the class.

me: For example, how can you make sure that class can be instantiated only once?
Colleague: Ummmm... (thinking for a while). I can declare a variable, let say count inside a class and will track object instances using that. So if count is 1, I won't allow any new object instantiation of that class.

me: But, that count variable (assuming he is referring to object variable) will be zero (or whatever set to default) for every new instance of that class so, how that will help you?
Colleague: No, no. It will be a static variable (class variable) and all object instances will share that.

me: Ya, you can track object instances using static variable. But for sharing that single instance of class at other places in your application, you either need to declare it globally or declare it as a static variable inside that class only. The later is good, because once you do that you probably don't need that static count variable. Ya, you don't need. Because you can always check if that instance is not null and that means it is already instantiated. So, return that instance only. Man, what we are discussing is nothing but a singleton pattern only.

So in Java, it will be like,


public class MyClass {
private static MyClass myClassUniqueInstance;

private MyClass() { }

public static synchronized MyClass getInstance() {
if (myClassUniqueInstance == null) {
myClassUniqueInstance = new MyClass();
}
return myClassUniqueInstance;
}
}


The synchronized keyword is added in getInstance() method to make it thread safe.

Okay, so trouble for posting this conversation on blog: To let you,
1. ask these kind of questions to yourself and/or others (may be good for interviewer)
2. answer these kind of questions (good for interviewee)
3. know at least one design pattern i.e. "The singleton pattern".