Design problem about inheritance
Hi everyone, this is the first time I post in this or any forum, so I hope I am doing it the correct way.
I have a problem at work with a bug where the application is throwing a ClassCastException, this is the scenario: The application authorizes transactions like sales, refunds, rollbacks. There is a base core module, which we are not allowed to modify, just use the classes in it and derive from them, so we have some POJOs that are used to store the transaction information, the basic structure is like this:
Code:
public class BaseTransaction{
...
}
public class ModuleTransaction extends BaseTransaction{
}
public class BaseRefundTransaction extends BaseTransaction{
}
public class ModuleRefundTransaction extends ModuleTransaction{
}
In the code, ModuleRefundTransaction uses a lot of things that come from ModuleTransaction, that´s why it is extending it and not BaseRefundTransaction .
The problem is that the base module does a lot of processing for refunds so, it is doing stuff like:
Code:
BaseRefundTransaction refundTxn = (BaseRefundTransaction )helper.getRefundTransaction();
and there we get the ClassCastException, because our helper is returning a ModuleRefundTransaction not a BaseRefundTransaction.
I have to fix this bug, but I don´t see any elegant solution, I think that the whole thing has a bad design, but maybe I am not experienced enough to see a good solution. The main problem is that we can´t change anything in the base module.
My first lazy thought was to start copying all the code in the base module into our module and use our class, but that's just not good.
Any suggestions? Thank you very much.
Re: Design problem about inheritance
gabyly,
It seems like you are trying to cast a class to an object, which Java doesn't like. How about instantiating it as a new class object first and then calling its methods, like this:
Code:
BaseRefundTransaction refundTxn = new BaseRefundTransaction();
refundTxn.helper.getRefundTransaction();
It's something along those lines, but the IDE should help figure it out for you.
Best regards,
Brian.
Re: Design problem about inheritance
Quote:
Originally Posted by
gabyly
I have to fix this bug, but I don´t see any elegant solution, I think that the whole thing has a bad design, but maybe I am not experienced enough to see a good solution. The main problem is that we can´t change anything in the base module.
The compiler just wants to prevent a crosscast (an upcast followed by a downcast in the same inheritance hierarchy). An upcast is always okay but a downcast may not be and isn't in this case.
The reason is that a cast is not a conversion. You can never cast an object into a type it isn't already. A ModuleRefundTransaction object can never be turned into a BaseRefundTransaction object regardless of what you try. You may be able fool the compiler with a bogus downcast but the runtime system will discover the fraud and throw an exception.
Quote:
My first lazy thought was to start copying all the code in the base module into our module and use our class, but that's just not good.
Inheritance has mainly two distinct uses; To inherit type (interface) for design, and to inherit implementation for code sharing. It's seldom a good idea to do both at the same time as you've noticed. So I suggest you make a better design based on a new set of interfaces. Objects of the old classes can then be used in the implementation of new classes, like say
Code:
interface NewInterface {
void newMethod();
}
//
class NewClass implements NewInterface {
OldClass o = new OldClass(); // delegated old class
void newMethod() {
o.someOldMethod(); // used as part of a new class implementation
// other code
}
}
In this way you get a new flexible design based on interfaces and you can still reuse the existing old class hierarchy motivated by code sharing, without resorting to code duplication. It remains of course to figure out what the new interface based design should look like but you probably have a fairly good idea since you know what doesn't work with the old design.