Search code examples
javaoopmultiple-inheritancediamond-problemmultiple-interface-implem

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.


Solution

  • 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.