How can I create singletons of derived classes? - java

I was asked this question in an interview . I have a base class (say class A) and then two subclasses B and C. Now I have no control over the constructor of B and C(those constructors can't be private , has to be public ) but the requirement is that every instance of B and Cshould be a singleton . How can I achieve this ?

I think I'd do this in the constructor for A. Get it to call this.getClass(), and use that to do a lookup in private HashSet. If you get a hit, then an instance of the class has previously been created, and you throw an exception.
public abstract class A {
private static HashSet<Class<?>> classes = new HashSet<Class<?>>();
public A () {
synchronized (classes) {
Class<?> c = this.getClass();
if (classes.contains(c)) {
throw NotSingletonException("Class " + c + " is not singleton");
}
classes.add(c);
}
}
}
If you arrange that all of A's constructors do this, then subclasses cannot avoid the check. And since the JLS won't let you put a try / catch around a this() or super() call, the constructor for the subclass can't ever return normally once that exception has been thrown.
I'd say that this is a pretty hard interview question ...
#emory comments:
What if B and C are not final? Then I could create classes B1, B2, C1, C2, etc.
The problem here (if it counts as a problem) is that the B1 and B2 instances are also B instances, and that means that the B instance is no longer a singleton ... depending on the definition of singleton you are aspiring to implement.
I can see a couple of ways of dealing with this:
You could reflectively test the subclass modifiers see if the classes are final, and refuse to create instances of non-final classes ... just in case.
You could replace the HashSet<Class> with a List<Class>. Then each time the A constructor is called, it would iterate over the list calling elem.isAssignableFrom(c) for each element class. If any call returns true, the (strict) singleton invariant is violated so an exception should be thrown.
The logic may need to be adjusted depending on the model of singleton-ness you are trying to enforce, but the general solution applies: record the classes and examine / compare new classes with previous ones.

I am showing it for the class B
Though you can use Double checked locking, and synchronized on method to do it.. i am showing you a quick and dirty way of doing it...
public class B {
private static B b = new B();
private B() {}
public static B getInstance() {
return b;
}
}

Related

Create single object using new keyword

The below question is asked by 4th round interview by project director.
There is a class A . Any number of classes can be derived from A. Constraints is any subclass derived from A or A itself , I should be able to create only one object per class using new keyword. If I try to creating another object it will throw exception.
Class B is derived class of A similarly class C, D, E are also derived classes. The number of class is not limited. Any number of classes can be derived.
The logic of restriction must be inside the class heirarchy not inside the main class.
Sample code of main class.
A obj1 = new A(); // object should create
A obj2 = new A(); // exception should throw
E Obj3 = new E(); //object should create
E obj4 = new E(); //Exception should throw
You can achieve that by storing a static reference to a collection holding instantiated classes (could be any data structure that works), then checking it in the constructor to avoid multiple instantiations:
class A {
private static Set<String> instantiatedClasses = new HashSet<>();
A() {
super();
if (instantiatedClasses.contains(getClass().getName())) {
throw new IllegalStateException(
"Cannot create multiple instances of " +getClass().getName());
}
instantiatedClasses.add(this.getClass().getName());
}
}
class B extends A {
}
And when that's tested:
A a = new A();
System.out.println("Created a: " + a);
try {
a = new A();
} catch (Exception e) {
e.printStackTrace();
}
a = new B();
System.out.println("Created b: " + a);
a = new B();
An output like this is produced:
Created a: stackoverflow.A#506e1b77
java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.A
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.Main.main(Main.java:14)
Created b: stackoverflow.B#9807454
Exception in thread "main" java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.B
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.B.<init>(Main.java:40)
at stackoverflow.Main.main(Main.java:21)
This is just exploiting the fact that a superclass's constructor is always invoked on instance creation for subclasses. And this will work even for arbitrary inheritance depths.
There are alternative ways of keeping track of classes that have been instantiated, one of which is storing the class, but I believe the necessary part is checking the type in the constructor (where the runtime classes can be seen, and before too late to prevent successful instantiation)
In class A: have a static set of class. Each time the constructor of A is invoked, use this.getClass() to acquire the actual class that wants to be instantiated (keep in mind that any sub class has to call a super constructor first).
If the class is stored in the set, throw that exception. If not, then store the class.
public class A {
private static final Set<Class<? extends A>> INSTANCE_HOLDER = new HashSet<>();
public A() {
if (INSTANCE_HOLDER.contains(this.getClass()))
throw new RuntimeException("can't create more than one instance.");
INSTANCE_HOLDER.add(this.getClass());
}
}
This should be enough to get you started.
For the record: although this should work, it seems like a rather odd idea. If you need singleton objects, rather look into using enums for example. That will prevent all the subtle issues, for example due multiple threads creating objects.
Or, as pointed out by the comment: what about the life time of these objects? You could use a map to ensure that references to your singletons are kept.
But in the end, all of this sounds like violations of the single responsibility principle.
You can use a static instance in A and then in the constructor check if an instance exists and if yes then throw an exception , if it does not then create an object. I am assuming that there is only one object of any class that is either A or a subclass of A. If you mean to say that there should be only instance for each subclass and A , then you may need to create a static HashMap with class Names as the key in A and then check if an instance exists for the particular class by checking for the className from the HashMap.

What happens in the heap when class A inherits class B in Java

In Java suppose we have two classes A and B such that B inherits A
and A has three private fields and a constructor with three parameters:
public class A {
private int a ;
private int b ;
private int c ;
public A(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
and here is class B
public class B extends A {
public B() {
super(1,2,3);
}
}
We consider the following test class
public class TestA {
public static void main(String[] args) {
A a = new A(1,2,3);
B b = new B();
}
}
The question is, what is the ordered process in the heap that occurs when creating the class A with private fields and inheriting it by the class B? What happens in the heap when creating instances of these two classes? How does the memory allocation happen and how the classes interact in the computer memory ?
We know also that a subclass can't inherit the private fields of its superclass, so what happens exactly when the constructor B() is called?
Class objects are loaded into the heap like any other object. This object just represents the Class.
Oracle official 'Understanding Memory guide'
and good old java specs , you can read the whole document as how the class loader works, you won't find anything that "Classes are loaded in Heap" .. Further more you can do some initial search on the internet for further clarification.
Class B will compile perfectly.
now your Questions by their order:
what is the ordered process in the heap that occurs when creating the class A with private fields and inheriting it by the class B?
You cannot determine their order its up to jvm as how it manages their order, private members are not inherited but exist in the instantiated object in the parent (super).
In other words, Yes, instances of the subclass will have copies of a private field of the parent class.
They will however not be visible to the subclass, so the only way to access them is via methods of the parent class.
What happens in the Heap when creating instances of these two classes?
Typically the sequence will be something like after you make instances of A and B
reference to the A.class object (after making Aclass instance)
reference to the B.class object (after making B class instance)
block of Object instance variables
block of A instance variables (only a,b,c)
block of B instance variables (none in this case)
however each implementation of a JVM is free to choose how it allocates each of them.
We know also that a subclass cant inherit the private fields of its superclass, so what happens exactly when the constructor B() is called?
When you Call B()
B b = new B();
it will call the super(1,2,3)
So what will happen after that ? nothing the values passed to super(); are passed to A(int a, int b, int c) and then assigned to the instance variables of A but this doesn't mean that those private fields are now accessible to B.. you just passed values to super class constructor thats all.
--EDIT--
If you want a much better understanding of of Heap and Stack, see this question
--EDIT-2--
If you take some time out to study this wiki , it has everything about JVM including its process in Heap and other memory structures
--Final EDIT-3--
In context of OP's comment regarding private members of Super class
Take a look at this The answers of this question will clear your confusion regarding inherited members and not accessible private members, since sub class instance is the instance of super class, it's instance has all the fields of father class ! Private members are not visible to that child !! Thats what JLS specification you're referring to! They take up their space inside the object. They are not visible to child class but they are there inside that instance.

Creating objects of a subclass as instances of the superclass in Java

say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
The output will be the following:
Doing something in A
Doing something in A
Doing something in A
Thus, my first question is: what is the meaning of the declaration like
A aInstance2 = new B();
i.e., why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration
B aInstance2 = new B();
?
If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to
Doing something in A
Doing something in B
Doing something in C
Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?
Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".
Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.
As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.
If you don't mind I will post a link with information about Static and Dynamic Binding
http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
Because static method is based on Reference type .
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
So internally it converts into :
A.doSth();
A.doSth();
A.doSth();
Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth(). Thus, each class provides its own implementation.
Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.
Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.
Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.
Illustration -
When doSth() is static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.
When doSth() is not static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.
static methods are at class level and act on the reference type(LHS of ==) unlike instance level methods which are dynamically dispatched based on the instance type(RHS of ==)

Class-specific method visibility

Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"
There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);
No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.
With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}

What is the best use of Inheritance other than reduce redundant code?

What is the best use of Inheritance, other than it will reduce redundant code!
Let us take an example
Class A:Base Class
Class B:Sub Class
and Class C.
CLASS A
^
| And CLASS C
|
|
CLASS B
i can use methods from Class A, in Class B by inheritance.
in the same i can use the methods from Class A, in Class C, by creating instance of Class A.(say A is Public)
using inheritance, only reduce creating new Object/Instance?
Plz help me to better understand!
A great benefit is polymorphism. If classes B and C both inherit from A, then whenever an object of type A is required, it can be replaced by either an object of type B or an object of type C. Assuming the corresponding methods are overriden in B and C, this is very handy to get different behavior depending on which object you pass.
Example:
class A {
public void foo() { System.out.println("A"); }
}
class B extends A {
public void foo() { System.out.println("B"); }
}
class C extends A {
public void foo() { System.out.println("C"); }
}
Then:
public static void printMessage(A obj) {
obj.foo();
}
public static void main(String[] args) {
A b = new B();
printMessage(b); // prints 'B'
A c = new C();
printMessage(c); // prints 'C'
}
The main point of inheritance is polymorphism: to allow other classes to use an instance of ClassB knowing only that it can be used as a ClassA.
My favourite example is streams - I could easily write a copyStream method taking an InputStream and an OutputStream for example, using only the methods declared on those types. Then I could copy a FileInputStream to a ByteArrayOutputStream, or use network-related streams etc, all without changing any of the code in the copyStream method.
The main reason to use inheritance is not to remove redundant code.
Inheritance and all magic made possible is a key, central point in OOP. Extending a class doesn't only allow you to use its functionality, but also modify (by polimorphism) and add more functionality.
The difference comes with the need to understand the ability to pass class B into functions that act on class A. In this sense B is-a type of A where class C has or owns A. The difference is small and only significant in certain circumstance.
That is not to say that the difference is often made explicit in code tbh. Often people will inherit when they really want ownership and sometimes they do ownership when an object really is-a type of something else.

Categories

Resources