Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Superclass to construct a subclass on certain conditions, possible?

I have this condition

public class A {
     public action() {
         System.out.println("Action done in A");
     }
}


public class B extends A {
     public action() {
         System.out.println("Action done in B");
     }
}

when I create an instance of B, the action will do just actions in B, as it overrides the action of the superclass.

the problem is that in my project, the super class A is already used too many times, and I am looking for a way that under certain conditions, when i create an instance of A it makes a check and if it is true, replace itself with B.

public class A {
     public A() {
         if ([condition]) {
            this = new B();
         }
     }

     public action() {
         System.out.println("Action done in A");
     }
}

A a = new A();
a.action();
// expect to see "Action done in B"...

is this possible in some way?

like image 777
ramihope Avatar asked May 05 '10 12:05

ramihope


People also ask

Can we create of subclass in superclass?

Creating SubclassesTo create a subclass of another class use the extends clause in your class declaration. (The Class Declaration explains all of the components of a class declaration in detail.) As a subclass, your class inherits member variables and methods from its superclass.

Can superclass access subclass fields Java?

Does a subclass have access to the members of a superclass? No, a superclass has no knowledge of its subclasses.

Can superclass object reference a subclass object?

First approach (Referencing using Superclass reference): A reference variable of a superclass can be used to a refer any subclass object derived from that superclass. If the methods are present in SuperClass, but overridden by SubClass, it will be the overridden method that will be executed.

Does the assignment of a superclass to a subclass require a cast?

Java doesn't allow assigning a superclass object to a subclass one. To do so would require explicit casting, or known as downcasting.


1 Answers

I would say that doing this:

this = new B();

within the constructor for A would violate OO design principles, even it were possible to do (and it isn't).

That being said, if I were faced with this scenario:

the problem is that in my project, the super class A is already used too many times

I would solve it in one of the two following ways:
I have assumed that your condition is that you do not want too many objects of type A, otherwise feel free to substitute in any other condition.

Option 1 : Use a factory design pattern.

public class AFactory
{
    private static count = 0;
    private static final MAX_COUNT = 100;

    public A newObject() {
        if (count < MAX_COUNT) {
            count++;
            return new A();
        } else {
            return new B();
        }
    }
}

And then somehwere else you generate the objects like so:

A obj1 = factory.newObject();
A obj2 = factory.newObject();

Option 2 : Static counter + try&catch

Use a static counter within your A class that keeps track of the number of times A has been instantiated, by incrementing the static variable by one in the constructor. If it hits a limit for the max number of object of type A, throw an InstantiationError in A's constructor.

This would mean that whenever you instantiate A, you have to a try..catch block to intercept the InstantionError, and then create a new object of type B instead.

public class A {

    private static count = 0;
    private static final MAX_COUNT = 100;

    public A() {
        if (count > 100) {
            throw new InstationError();
        }
    }

}

And when generating your objects:

A obj1, obj2;
try {
    obj1 = new A();
} catch (InstantiationError ie) {
    obj1 = new B();
}
try {
    obj2 = new A();
} catch (InstantiationError ie) {
    obj2 = new B();
}

Option 2 is closest to what you ask directly in the question. However, I would personally choose to use the factory design pattern, because it is much more elegant solution, and it allows you to achieve what you want to do anyway.

like image 137
bguiz Avatar answered Nov 02 '22 23:11

bguiz