The problem is this: I have an abstract class that does some work in its constructor, and a set of child classes that implement the abstract class:
class Abs
Two comments: Firstly, you're not supposed to think in terms of 'jumping over' constructors like this. Secondly, it really sounds like you need to rethink your class relationships.
Any time you find yourself thinking "A extends B, except that..." is a very good time to look at things further. 'Extends' implies 'is a', which is an either/or relationship: having optional behaviour adds grey areas which will bite you later on.
As people have said, you could provide multiple constructors on ConcreteClass1 to do the initialization you require in each case, maybe making them protected so that they can only be used by subclasses. But here's a question: what if someone wants to write CustomizedClass2 that needs some (but not all) of the functionality in ConcreteClass1? Do you add another custom constructor?
Easy (but why?):
class AbstractClass {
AbstractClass(){ /* useful implementation */ }
}
class ConcreteClass1 extends AbstractClass {
ConcreteClass1(){ super(); /* useful implementation */ }
ConcreteClass1(boolean skip){ super(); }
}
class CustomizedClass1 extends ConcreteClass1 {
CustomizedCLass1(){ super(true); /* useful implementation */ }
}
This sounds to me like a mixture of concerns - something Java is not well equipped to handle.
While it is not the answer you were hoping for or one that I am proud to type, you could simply create ConcreteClass2
that mimics ConcreteClass1
and uses the AbstractClass
's constructor.
As @TofuBeer said, this is not something that Java supports. This is why some modern languages (i.e. Scala w/ Traits) are gaining passionate developers.
One way I came up with:
class AbstractClass {
AbstractClass(){ init(); }
protected init(){ /* useful implementation */ }
}
class ConcreteClass1 extends AbstractClass {
ConcreteClass1(){ init(); /* useful implementation */ }
}
class CustomizedClass1 extends ConcreteClass1 {
CustomizedCLass1(){ init(); /* useful implementation */ }
}
In this way, CustomizedClass1 gets the behavior it needs from AbstractClass without passing through ConcreteClass1 initializations.
EDIT: Ouch, this doesn't work because the parent's constructors are implicitly called as one of the commenters pointed out, I think the easy way is to have different constructors.