Java multiple class compositing and boiler plate reduction
We all know why Java does/should not have multiple inheritance. So this is not questioning about what has already been debated till-cows-come-home.
This discusses what we would do when we wish to create a class that has the characteristics of two or more other classes.
Probably, most of us would do this to "inherit" from three classes. For simplicity, I left out the constructor.:
class Car
extends Vehicle
{
final public Transport transport;
final public Machine machine;
}
So that, Car class directly inherits methods and objects of Vehicle class, but would have to refer to transport and machine explicitly to refer to objects instantiated in Transport and Machine.
Car car = new Car();
car.drive(); // from Vehicle
car.transport.isAmphibious(); // from Transport
car.machine.getCO2Footprint(); // from Machine
I thought this was a good idea until when I encounter frameworks that require setter and getter methods. For example, the XML
<Car amphibious='false' footPrint='1000' model='Fordstatic999'/>
would look for the methods setAmphibious(..), setFootPrint(..) and setModel(..). Therefore, I have to project the methods from Transport and Machine classes
class Car
extends Vehicle
开发者_运维技巧{
final public Transport transport;
final public Machine machine;
public void setAmphibious(boolean b){
this.transport.setAmphibious(b);
}
public void setFootPrint(String fp){
this.machine.setFootPrint(fp);
}
}
This is OK, if there were just a few characteristics. Right now, I am trying to adapt all of SmartGWT into GWT UIBinder, especially those classes that are not a GWT widget. There are lots of characteristics to project.
Wouldn't it be nice if there exists some form of annotation framework that is like this:
class Car
extends Vehicle
@projects {Transport @projects{Machine @projects Guzzler}}
{
/* No need to explicitly instantiate Transport, Machine or Guzzler */
....
}
Where, in case of common names of characteristics exist, the characteristics of Machine would take precedence Guzzler's, and Transport's would have precedence over Machine's, and Vehicle's would have precedence over Transport's. The annotation framework would then instantiate Transport, Machine and Guzzler as hidden members of Car and expand to break-out the protected/public characteristics, in the precedence dictated by the @project annotation sequence, into actual source code or into byte-code. Preferably into byte-code. So that the setFootPrint method is found in both Machine and Guzzler, only that of Machine's would be projected.
Questions:
- Don't you think this is a good idea to have such a framework?
- Does such a framework already exist? Tell me where/what.
- Is there an eclipse plugin that does it?
- Is there a proposal or plan anywhere that you know about such an annotation framework?
It would be wonderful too, if the annotation/plugin framework lets me specify that boolean, int, or whatever else needs to be converted from String and does the conversion/parsing for me too.
Please advise, somebody. I hope wording of my question was clear enough. Thx.
Edited: To avoid OO enthusiasts jumping to conclusion, I have renamed the title of this question.
Perhaps not exactly what you are looking for, but you can take a look at Mixins:
- the wikipedia article
- Qi4j framework
- CGLIB's mixin support
- this example
If you have some freedom in your environment, definitely take a look at Scala. It has traits that will let you solve this problem cleanly. Traits are compositional (pdf), and offer a much better code-reuse strategy than inheritance.
Back in Java land, you can use AspectJ Inter-Type Declarations to achieve something similar (mixins). There's also a very nice Eclipse plugin for it: AJDT.
Some frameworks (at least Spring) support specifying a path for setters and getters. So a setter would look more like
<property name="transport.amphibious" value="true" />
You should see if you can make usage of such options.
精彩评论