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 AbstractClass {
AbstractClass(){ /* useful implementation */ }
}
class ConcreteClass1 extends AbstractClass {
ConcreteClass1(){ super(); /* useful implementation */ }
}
Then, the concrete classes need to be customized and one solution is to extend the concrete classes:
class CustomizedClass1 extends ConcreteClass1 {
CustomizedCLass1(){ super(); /* useful implementation */ }
}
BUT the problem is that the customized classes need only to call the abstract class's constructor and not the concrete class's constructor.
How do you achieve this? Suggestions to change the class's relationships are valid.
EDIT: The concrete example is that ConcreteClass1 and CustomizedClass1 have different sets of data (ConcreteData1 and CustomizedData1), and it is retrieved from the database in the class's constructor. The problem is that creating an instance of CustomizedClass1 will retrieve both data entities.
I am aware that using simple inheritance it's probably not the best thing to do, that's why I pointed out that suggestions to change the class's relationships are valid.
Is CustomizedData1 a subclass of ConcreteData1? If so, then I would suggest having a (possibly protected) constructor for ConcreteClass1 that takes in a ConcreteData1 to use instead of fetching its own during initialization. This way, CustomizedClass1 can fetch its CustomizedData1 and pass it to its call to super. Unfortunately this may be tricky or fairly impossible if you can't fetch the data prior to some internal init.
class ConcreteClass1 extends AbstractClass {
ConcreteClass1(){
this(...fetch data as before...);
}
ConcreteClass1(ConcreteData1 data){
myData = data;
...
}
}
class CustomizedClass1 extends ConcreteClass1 {
CustomizedCLass1(){
super(new CustomizedData1(...));
...
}
}
But then CustomizedClass1 probably needs a reference to the data as a CustomizedData1 not merely a ConcreteData1. It could just typecast its inherited ConcreteData1 all the time, but that seems yucky. But if it stores its own reference to the data, then there is a need to keep the references in sync if they're not final.
You cannot do this in Java. I frequently have students who want to do this, but I have never seen a case where it is really what they wanted to do.
Can you give a concrete example of what it is you want to do and why (your description is too vague) and I am sure a solution can be achieved :-)
Edit:
For a real world example of why you do not want to do this (normally) would be a hierarchy like:
Animal (constructor makes the eyes)
|
Mammal (constructor makes the lungs)
|
Human (constructor sets the language)
If the Human constructor could skip over the Mammal constructor then you would wind up with a Human who has no lungs... not very useful.
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 */ }
}
Any instance of CustomizedClass1
is also an instance of ConcreteClass1
, by definition, so it must be constructed as a valid ConcreteClass1
instance before the CustomizedClass1
constructor can run. Otherwise, what would happen if you called ConcreteClass1
methods on it? They'd be trying to operate on variables that haven't been initialized yet.
If you think you need to do this, chances are your design needs re-thinking. If you only want some of the functionality from ConcreteClass1
, for example, that functionality could be factored out into a superclass of ConcreteClass1
, and CustomizedClass1
could extend that to get just the functionality that it needs.
Please provide more information about the relationship between these classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With