There are numerous hints that inheritance is not very stable under refactoring; see, for example, Bloch, "Effective Java".
We therefore suggest to prefer composition (=delegation) over inheritance where this is possible. It is only possible when the class that one wants to inherit from implements an interface. In that case, the following is possible (with eclipse):
1. Write a class skeleton as follows:
class MyClass implements XXXInterface {
private XXXInterface delegate = new XXXImplementation(...) ;
}
2. In eclipse, go to "source"/"generate delegate methods" and follow the instructions.
[[Somebody please add a screenshot here. thanks. kai]]
This will delegate all method calls to MyClass to the delegate. Now you can modify some of the delegate methods as you like.
(This sometimes seems to provide less access than inheritance, but I don't think this is true as long as you assume that internal variables/fields are always private.)
It is called "composition" since you can do this with more than one interface/delegate. The classical example is something like
class MyCar implements HasSteering, HasBrakes, HasGears {
private HasSteering steeringDelegate = new PowerSteering(...) ;
private HasBrakes brakesDelegate = new SimpleBrakes(...) ;
private HasGears gearsDelegate = new ElectronicGears(...) ;
}
where the eclipse generate delegate methods will produce methods such as
public void steerToRight( double value ) {
steeringDelegate.steerToRight( value ) ;
}
...
public void brake( double value ) {
brakesDelegate.brake( value ) ;
}
As one can see, this now allows operations such as
MyCar car ... ... car.brake( 3. ) ; car.steerToRight( 0.3 ) ;
that is, the car is now composed of its internals.
In MATSim, we often expose the delegation, that is, the syntax is
car.getBrakes().brake( 3. ) ; car.getSteering().steerToRight( 0.3 ) ;
This has the advantage that, if you extend the interfaces, you do not need to adapt every implementation. It is, clearly, not an option if you want to write a class (such as a PlanStrategy) that is later inserted into the code – that has to fulfill the contract defined by the interface.