views:

211

answers:

3

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:

  1. Don't you think this is a good idea to have such a framework?
  2. Does such a framework already exist? Tell me where/what.
  3. Is there an eclipse plugin that does it?
  4. 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.

+2  A: 

Perhaps not exactly what you are looking for, but you can take a look at Mixins:

Bozho
Interesting stuff, but IMO could be kind of annoying. On the mixin side would it be worth mentioning Groovy which is (as you know) a Java superset with mixins (http://groovy.codehaus.org/Runtime+mixins)
Yar
A: 

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.

Robin
I am specifically working on adapting SmartGWT to UIBinder right now and what you recommend is undoable in UIBinder.
Blessed Geek
+1  A: 

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.

Jordão