Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative for multiple inheritance [duplicate]

After 20 or so years programming Java for the first time I wish I had multiple inheritance. But I don't so I'm looking for an alternative for this concrete problem.

The real application is some kind of ERP and somewhat complex so I try to translate this problem to cars. This only goes so far but it's the best I can do.

Lets start with an interface describing what a car can do:

public interface Car {      public String accelerate();     public String decelerate();      public String steerLeft();     public String steerRight(); } 

Now we have a basic (but not abstract) implementation:

public class BasicCar implements Car {      protected final String name;      public BasicCar( String name ) {          this.name = name;     }      // In the real word this method is important and does lots of stuff like calculations and caching     protected String doDrive( String how ) {         return name + " is " + how + "ing";     }     @Override     public String accelerate() {         return doDrive( "accelerat" );     }     @Override     public String decelerate() {         return doDrive( "decelerat" );     }       // This method is important, too     protected String doSteer( String where ) {         return name + " is steering to the " + where;     }     @Override     public String steerLeft() {         return doSteer( "left" );     }     @Override     public String steerRight() {         return doSteer( "right" );     } } 

In the real world this itself is a facade to a DAO. Note that I need the methods doDrive and doSteer to be there because this is where the real work like some calculations, translations and caching is done.

And some more concrete implementations:

public class Sportscar extends BasicCar {      public Sportscar( String name ) {         super( name );     }      // I need to call the super method     @Override     public String doDrive( String how ) {         return super.doDrive( how ) + " fastly";     } }  public class Truck extends BasicCar {      public Truck( String name ) {         super( name, new BasicMotor(), new TruckySteerer() );     }      // I need to call the super method     @Override     public String doSteer( String where ) {         return super.doSteer( where ) + " carefully";     } } 

What I can do right now is:

Car mcqueen = new Sportscar( "McQueen" ); mcqueen.steerLeft() //-> "McQueen is steering left" mcqueen.accelerate() // -> "McQueen is accelerating fastly"  Car mack = new Truck( "Mack" ); mack.steerLeft() //-> "Mack is steering left carefully" mack.accelerate() // -> "Mack is accelerating" 

What I now want to do is combining these two into one which shares their functionallity:

Car red = new Firetruck( "Red" ); red.steerLeft() //-> "Red is steering left *carefully*" red.accelerate() // -> "Red is accelerating *fastly*" 

What I tried / thought about

I could copy&paste code from both into one class. But this is never a good idea. And in the real application this is pretty much code so it's an even worse idea.

I think I'm facing some major rewrite/refactoring here.

So I could make Sportscar and Truck a Decorator and for Firetruck use both. But this won't work because doSteer and doDrive are called from within the decorated objects whereas a decorator only works for calles from the "outside". So I would have to put these methods in the decorator, too and this isn't a good idea either.

So I could use Java8's new fancy features and make doSteer and doDrive delegating to an interface like:

@FunctionalInterface interface Driver {     public String doDrive( String where ); } 

And feeding it to the constructor of BasicCar but then (apart from getting pretty complex and getting some other rather nasty java problems with final) I don't have access to the state of BasicCar in a good way anymore.

So currently I'm a little lost here. Any good ideas would be appretiated.

EDIT: To give an example how this looks in the real world: The doSteer group could be something like:

class ProductImpl {     String getTitle(){         return getField( "title" );     }     String getTeaser(){         return getField( "teaser" );     }     String getField( String name ){         Locale loc = configuredLocale();         Map vars = configuredVarialbes();         String value = getCached( name, loc );         value = translateVariables( value );         value = replaceVariables( value, vars );         // and more     } } 
like image 562
Scheintod Avatar asked Mar 26 '15 10:03

Scheintod


People also ask

What is the replacement of multiple inheritance?

Interfaces provide an alternative to multiple inheritance. Java programming language does not support multiple inheritance. But interfaces provide a good solution. Any class can implement a particular interface and importantly the interfaces are not a part of class hierarchy.

What is an alternative design to avoid multiple inheritance?

You could use pattern strategy to define different behaviors and make the subclasses implement them.

Is there any alternative solution for inheritance?

Delegation can be an alternative to inheritance. Delegation means that you use an object of another class as an instance variable, and forward messages to the instance.

What is used instead of multiple inheritance in Java?

However, a class can implement one or more interfaces, which has helped Java get rid of the impossibility of multiple inheritances. The reason behind this is to prevent ambiguity. Consider a case where class B extends class A and Class C and both class A and C have the same method display().


1 Answers

You could use pattern strategy to define different behaviors and make the subclasses implement them.

Like in this picture : Pattern strategy

It's French (dictionary below) but pretty self-explanatory :

  • All the classes that inherit from Personnage are characters used in a video game.
  • All the classes that implement an interface (EspritCombatif, Deplacement, Soin) define the method in the interface. They are the behaviors.
  • The Personnage class contains an object of each of the interfaces defined on the right.
  • Each character (subclass of Personnage) chooses what code to implement by doing for example a combat = new CombatCouteau(); in the constructor.

So if you want to change only the behavior of all the guys that fight with a knife, you just change the code in CombatCouteau.


Dictionary :

  • Personnage = Character
  • Guerrier = Warrior
  • Medecin = Doctor
  • Chirurgien = Surgeon
  • Couteau = Knife
  • Pistolet = Gun
  • Marcher = Walk
  • Courir = Run
  • Premier soin = First aid
  • Opération = Surgery
  • Esprit combatif = Combative mind
  • combat, combattre = fight, to fight
  • déplacement, se déplacer = moving, to move
  • soin, soigner = healing, to heal
like image 129
Gabriel Avatar answered Sep 20 '22 09:09

Gabriel