Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Multiple Inheritance

In an attempt to fully understand how to solve Java's multiple inheritance problems I have a classic question that I need clarified.

Lets say I have class Animal this has sub classes Bird and Horse and I need to make a class Pegasus that extends from Bird and Horse since Pegasus is both a bird and a horse.

I think this is the classic diamond problem. From what I can understand the classic way to solve this is to make the Animal, Bird and Horse classes interfaces and implement Pegasus from them.

I was wondering if there was another way to solve the problem in which I can still create objects for birds and horses. If there was a way to be able to create animals also that would be great but not necessary.

like image 796
Sheli Avatar asked Feb 17 '14 08:02

Sheli


People also ask

Can you have multiple inheritance in Java?

The Java programming language supports multiple inheritance of type, which is the ability of a class to implement more than one interface. An object can have multiple types: the type of its own class and the types of all the interfaces that the class implements.

What is multiple inheritance in Java with example?

When one class extends more than one classes then this is called multiple inheritance. For example: Class C extends class A and B then this type of inheritance is known as multiple inheritance. Java doesn't allow multiple inheritance.

Why multiple inheritance is not in Java?

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(). Now java compiler cannot decide, which display method it should inherit. To prevent such situation, multiple inheritances is not allowed in java.

Why do we do multiple inheritance?

Multiple inheritance is useful when a subclass needs to combine multiple contracts and inherit some, or all, of the implementation of those contracts. For example, the AmericanStudent class needs to inherit from both the Student class and the American class.


2 Answers

You could create interfaces for animal classes (class in the biological meaning), such as public interface Equidae for horses and public interface Avialae for birds (I'm no biologist, so the terms may be wrong).

Then you can still create a

public class Bird implements Avialae { } 

and

public class Horse implements Equidae {} 

and also

public class Pegasus implements Avialae, Equidae {} 

Adding from the comments:

In order to reduce duplicate code, you could create an abstract class that contains most of the common code of the animals you want to implement.

public abstract class AbstractHorse implements Equidae {}  public class Horse extends AbstractHorse {}  public class Pegasus extends AbstractHorse implements Avialae {} 

Update

I'd like to add one more detail. As Brian remarks, this is something the OP already knew.

However, I want to emphasize, that I suggest to bypass the "multi-inheritance" problem with interfaces and that I don't recommend to use interfaces that represent already a concrete type (such as Bird) but more a behavior (others refer to duck-typing, which is good, too, but I mean just: the biological class of birds, Avialae). I also don't recommend to use interface names starting with a capital 'I', such as IBird, which just tells nothing about why you need an interface. That's the difference to the question: construct the inheritance hierarchy using interfaces, use abstract classes when useful, implement concrete classes where needed and use delegation if appropriate.

like image 195
Moritz Petersen Avatar answered Nov 15 '22 23:11

Moritz Petersen


There are two fundamental approaches to combining objects together:

  • The first is Inheritance. As you have already identified the limitations of inheritance mean that you cannot do what you need here.
  • The second is Composition. Since inheritance has failed you need to use composition.

The way this works is that you have an Animal object. Within that object you then add further objects that give the properties and behaviors that you require.

For example:

  • Bird extends Animal implements IFlier
  • Horse extends Animal implements IHerbivore, IQuadruped
  • Pegasus extends Animal implements IHerbivore, IQuadruped, IFlier

Now IFlier just looks like this:

 interface IFlier {      Flier getFlier();  } 

So Bird looks like this:

 class Bird extends Animal implements IFlier {       Flier flier = new Flier();       public Flier getFlier() { return flier; }  } 

Now you have all the advantages of Inheritance. You can re-use code. You can have a collection of IFliers, and can use all the other advantages of polymorphism, etc.

However you also have all the flexibility from Composition. You can apply as many different interfaces and composite backing class as you like to each type of Animal - with as much control as you need over how each bit is set up.

Strategy Pattern alternative approach to composition

An alternative approach depending on what and how you are doing is to have the Animal base class contain an internal collection to keep the list of different behaviors. In that case you end up using something closer to the Strategy Pattern. That does give advantages in terms of simplifying the code (for example Horse doesn't need to know anything about Quadruped or Herbivore) but if you don't also do the interface approach you lose a lot of the advantages of polymorphism, etc.

like image 23
Tim B Avatar answered Nov 15 '22 22:11

Tim B