How Do Java Interfaces Simulate Multiple Inheritance

How do Java Interfaces simulate multiple inheritance?

Suppose you have 2 kinds of things in your domain : Trucks and Kitchens

Trucks have a driveTo() method and Kitchens a cook() method.

Now suppose Pauli decides to sell pizzas from the back of a delivery truck. He wants a thing where he can driveTo() and cook() with.

In C++ he would use multiple inheritance to do this.

In Java that was considered to be too dangerous so you can inherit from a main class, but you can "inherit" behaviors from interfaces, which are for all intents and purposes abstract classes with no fields or method implementations.

So in Java we tend to implement multiple inheritance using delegations :

Pauli subclasses a truck and adds a kitchen to the truck in a member variable called kitchen. He implements the Kitchen interface by calling kitchen.cook().

class PizzaTruck extends Truck implements Kitchen {
Kitchen kitchen;

public void cook(Food foodItem) {
kitchen.cook(foodItem);
}
}

He is a happy man because he can now do things like ;

pizzaTruck.driveTo(beach);
pizzaTruck.cook(pizzaWithExtraAnchovies);

Ok, this silly story was to make the point that it is no simulation of multiple inheritance, it is real multiple inheritance with the proviso that you can only inherit the contract, only inherit from empty abstract base classes which are called interfaces.

(update: with the coming of default methods interfaces now can also provide some behavior to be inherited)

Multiple inheritance on Java interfaces

Multiple inheritance of implementations is not allowed. Components can inherit multiple interfaces, though.

Inheriting multiple interfaces isn't problematic, since you're simply defining new method signatures to be implemented. It's the inheritance of multiple copies of functionality that is traditionally viewed as causing problems, or at the very least, confusion (e.g., the diamond of death).

Java Multiple Inheritance

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.

How to define classes & interfaces in Java for a special multiple inheritance situation

You will have to shuffle around some of your classes and create new interfaces.

class Actor {
// Use Greenfoot Actor class instead of this one
}

interface ITransportation {

public void load(Transportable goods);
}

class Transportation extends Actor implements ITransportation{

@Override
public void load(Transportable goods) {

}
}

class Truck extends Transportation{

}

interface ITransportable {

}

class Transportable extends Actor implements ITransportable {

}
class Container extends Transportable {

}

class HybridGood implements ITransportable, ITransportation {

private Transportation transportation;
private Transportable transportable;

@Override
public void load(Transportable goods) {
transportation.load(goods);
}
}
class Bike extends HybridGood {

}

With this approach, you will be able to

  • Share the common functionality of Transportation and Transportable

    type in HybridGoods class.
  • You can access Actor type in load/unload method.

Does really interfaces can be use to achieve multiple inheritance

Interfaces give you multiple inheritance of a type, but not behaviour. A class implementing List and Map is a "ListMap", but the implementation has nothing (necessarily) to do with any existing List or Map implementation.

Of course using composition (which should be favored anyways), you could easily create a ListMap which delegates the calls accordingly to its list and map properties, while providing some presumably useful function that would combine their respective data.

With Java 8 interfaces are allowed default methods, so inheritance of behaviour is now also possible.

Multiple Inheritance in java

It was a design decision of Java. You'll never get it, so don't worry too much about it. Although MI might help you make Mixins, that's the only good MI will ever do you.

Is that Considered Multiple Inheritance

Answer NO.

In java only exist simple-inheritance.

public class A {  // Extends from `Object` class
}

class B extends A { // Extends from `A`
}

class C extends B { // Extends from `B`
}

What you have here is

C is a B , B is a A , A is an Object

(C is A by transitivity)

Multiple inheritance would be

C is a B and also is a D, D is an object, B is a A , A is an Object

In java is not allowed multiple inheritance (having more than one parent).

What you can do is implements multiple interfaces and there you can have a kind of multiple inheritance.

How can interfaces replace the need for multiple inheritance when have existing classes

You should probably favor composition (and delegation) over inheritance :

public interface TaggedInterface {
void foo();
}

public interface XMLElementInterface {
void bar();
}

public class Tagged implements TaggedInterface {
// ...
}

public class XMLElement implements XMLElementInterface {
// ...
}

public class TaggedXmlElement implements TaggedInterface, XMLElementInterface {
private TaggedInterface tagged;
private XMLElementInterface xmlElement;

public TaggedXmlElement(TaggedInterface tagged, XMLElementInterface xmlElement) {
this.tagged = tagged;
this.xmlElement = xmlElement;
}

public void foo() {
this.tagged.foo();
}

public void bar() {
this.xmlElement.bar();
}

public static void main(String[] args) {
TaggedXmlElement t = new TaggedXmlElement(new Tagged(), new XMLElement());
t.foo();
t.bar();
}
}


Related Topics



Leave a reply



Submit