I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
@Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
@Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?