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.
I have a stupid idea:
May I suggest the concept of Duck-typing?
Most likely you would tend to make the Pegasus extend a Bird and a Horse interface but duck typing actually suggests that you should rather inherit behaviour. As already stated in the comments, a pegasus is not a bird but it can fly. So your Pegasus should rather inherit a
Flyable
-interface and lets say aGallopable
-interface.This kind of concept is utilized in the Strategy Pattern. The given example actually shows you how a duck inherits the
FlyBehaviour
andQuackBehaviour
and still there can be ducks, e.g. theRubberDuck
, which can't fly. They could have also made theDuck
extend aBird
-class but then they would have given up some flexibility, because everyDuck
would be able to fly, even the poorRubberDuck
.It is safe to keep a horse in a stable with a half door, as a horse cannot get over a half door. Therefore I setup a horse housing service that accepts any item of type horse and puts it in a stable with a half door.
So is a horse like animal that can fly even a horse?
I used to think a lot about multiple inheritance, however now that I have been programming for over 15 years, I no longer care about implementing multiple inheritance.
More often than not, when I have tried to cope with a design that pointed toward multiple inheritance, I have later come to release that I had miss understood the problem domain.
OR
You could create interfaces for animal classes (class in the biological meaning), such as
public interface Equidae
for horses andpublic interface Avialae
for birds (I'm no biologist, so the terms may be wrong).Then you can still create a
and
and also
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.
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.To solve the problem of mutiple inheritance in Java → interface is used
J2EE (core JAVA) Notes By Mr. K.V.R Page 51
As you will already be aware, multiple inheritance of classes in Java is not possible, but it's possible with interfaces. You may also want to consider using the composition design pattern.
I wrote a very comprehensive article on composition a few years ago...
https://codereview.stackexchange.com/questions/14542/multiple-inheritance-and-composition-with-java-and-c-updated