Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choose which subclass to extend from at runtime in java

I have two classes (say B & C) that both derive from a class (say A). Now I need to write a class (say D) that should dynamically derive either from B or C at runtime.

B, C & A are classes provided to me through libraries and the only class in my control is D class. How do I write D with respect to constraints mentioned above. Obviously B and C have come from different vendors and hence would need different methods to be overridden in D depending on which is its parent class.

I cannot write different versions of D that would subclass from B & C since the override methods would have same code under different method names.

like image 487
Varun Bhatia Avatar asked Sep 28 '22 05:09

Varun Bhatia


1 Answers

You should define an interface I, then define concrete implementations that correspond to B and C. At runtime you can determine which implementation of I is necessary, perhaps using a factory method. Then your code need only call methods of I instead of methods of B or C.

EDIT

There seems to be some confusion about how this works. What you want is for your business logic to operate on a consistent, stable API that belongs to you. For this you create an interface which we'll call I. Now you need implementation classes for the different external classes you need to adapt to (A, B, and C). It might look something like this:

public interface I {
    void doSomething();
}

public class IA implements I {
    private A a;

    public IA(A a) {
        this.a = a;
    }

    public void doSomething() {
        // specific to A
        a.doSomethingUnique();
    }
}

// similar implementation classes for B and C

Now you need to obtain an instance of I at runtime specific to your current situation. Whatever informs you about which specific class is in use at runtime can be used for this purpose. At worst, you can do this:

// in some util class
public static I getI(Object obj) {
    if (obj instanceof A) {
        return new IA((A) obj);
    } else if (obj instanceof B) {
        return new IB((B) obj);
    } else if (obj instanceof C) {
        return new IC((C) obj);
    }
    // maybe throw an exception? or return a mock I implementation?
}

Now all your business logic refers only to instances of I and calls methods defined in your interface, abstracting away the different concrete classes you have no control over.

like image 152
Karakuri Avatar answered Oct 13 '22 03:10

Karakuri