转载 2012年03月26日 01:12:08


Java was designed without multiple inheritance. While some developers think of this as a flaw, it is actually true that the overall design of Java supports the solution of problems commonly solved with multiple inheritance in other ways. In particular, the singly rooted hierarchy (with Object as the ultimate ancestor of all classes) and Java interfaces solves most problems that are commonly solved using multiple inheritance in C++.

However, there are a few situations in which multiple inheritance is very helpful. In this note we will consider one special case and also the general case of multiple inheritance.

Mixin Inheritance

In mixin inheritance, one class is specifically designed to be used as one of the classes in a multiple inheritance scheme. We say that it provides some functionality that is "mixed in" to some other class that wants this functionality. Another way to think of mixin inheritance is that a mixin class is given a new parent class so that the mixin seems to extend the other class. In some projects it is necessary to rely on common services that must be provided by several classes. Mixin inheritance is one way to centralize the development of these services.

To provide for mixin inheritance we will need to define two interfaces as well a at least one class that provides the service: the Mixin class. In some situations, one of these interfaces is empty and may then be omitted.

The Interfaces

The first interface (always required) defines what the mixin class will provide for services. It defines one or more methods that will be implemented by the mixin class. We will take a simple and abstract example here. The class will be called (abstractly) MProvides to emphasize that it defines what any compatible mixin must provide. We will also assume that the only service provided is a void function and we will give it the abstract name func. In practice, however, there may be any number of methods defined and they may have any signatures.

interface MProvides
{	void func();

One special feature of mixin inheritance that is not usually present in the general multiple inheritance case is that the mixin class may require services of the class into which it is mixed. That is, in order to provide the "func" service, the mixin may need to get some information from the other class. We define this with another interface. We will give it the abstract name MRequires to indicate that it requires one or more services from the class into which it is mixed.

Here we will suppose that the compatible mixins require that the other class provides a method getValue that returns an int.

interface MRequires
{	int getValue();

In general, MRequires will have a more appropriate name and will have one or more methods of arbitrary signature. However, any class into which we mix our mixin must provide services with the given names and signatures, though it need not explicitly implement the MRequires interface. If MRequires is empty it may be omitted.

The Mixin

The mixin class itself will implement the MProvides interface. It will also be created by passing its constructor an argument that implements MRequires. Here is a simple example called (again abstractly) Mixin.

class Mixin implements MProvides
{	public Mixin(MRequires parent) { this.parent = parent; }

	public void func() { System.out.println("The value is: " + parent.getValue()); }

	private final MRequires parent;

When a new Mixin is created it knows about an MRequires object. It can then query this object using the services defined in MRequires in order to provide its own services. We have called this object parent to emphasize that the intent is to simulate giving the Mixin class a new parent class. If MRequires is empty, no object need be passed into the constructor. Note that in general, the Mixin constructor may require other parameters as well.

The Class Used as the Base

Now suppose that we wish to mix this class into another class. This class must have all of the methods required of the MRequires interface, but it need not implement this interface. It will probably have other methods as well. Here is an example.

Class Parent
{	public P(int value ) { this.val = value; }
	public int getValue() { return this.val; }
	public toString() { return "" + this.val; }
	private int val;

The Result of Mixing

Now, to actually mix the two classes together we first build a new class that extends Parent and implements both of our interfaces

class Child extends Parent implements MRequires, MProvides

This class defines both the services of Parent and those of the mixin (MProvides). To implement the Child class we create a new Mixin object and save it. We will also delegate all messages defined in the MProvides interface to this object. When we create the Mixin object we need to pass it an object that implements MRequires, but this object does so as this new class implements the MRequires interface.

	public Child(int value)
	{	super(value); 
		this.mixin = new Mixin(this);

	public void func(){ mixin.func(); }

	private final MProvides mixin;


Note that the service named func is provided by the Mixin object as previously defined. It does not need to be redefined in the Child class. Also note that the Child class automatically implements MRequires since the inherited method fulfills the necessary contract defined by the MRequires interface. We do have to provide the simple delegation function for the method(s) of MProvides, however.

The key here is that we were able to design the Mixin class to be a mixin and so define the two required interfaces. Note that it is actually the services defined by MProvides that are mixed in, not, properly speaking, the Mixin class itself. This actually adds some flexibility since several classes might implement this interface and so be mixed in to other classes to provide this form of multiple inheritance.

General Multiple Inheritance

We can use the above to see how to provide general multiple inheritance. The difference here is that we may not be able to design one of the classes to be a mixin. In the usual case, the two classes are predefined and do not require services from each other. This means that the MRequires interface is not needed. However, we still need to define one interface, since Java won't let us mix two classes together.

If we do have the luxury of designing at least one of the classes then we can proceed as before, treating that class as the mixin and defining an interface that it will implement. Otherwise we need to do a bit more. Suppose that we would like to mix the class Parent of the previous section with a class Other defined below.

Class Other
{	public Other(int value) { ... }
	public void whatever()

Since Java will let us extend only one class, we need to define an interface that declares the public features of the other. We will do this to make our life simple here, though you may choose to do the next step for the class of least importance and whose methods are going to be called least often. Here we will define an interface to give the public methods of the class Other.

Interface OtherInterface
{	void whatever();

We can now build a subclass of Other by doing nothing more than implementing this new interface and providing any required constructors (which are not inherited).

class OtherChild extends Other implements OtherInterface
{	public OtherChild (int value){ super(value); }

If we had the freedom to modify class Other we could avoid the class OtherChild and just have Other implement this new interface.

This new class is just like an Other, but it advertises that it implements the OtherInterface. From here we can proceed as in the mixin case by extending the Parent class, implementing he OtherInterface and creating a new OtherChild object to which we delegate the messages defined in the OtherInterface.

Class ParentChild extends Parent implements OtherInterface
{	public ParentChild(...) { child = new OtherChild(...); ... }

	public void whatever() { child.whatever(); }

	private final OtherInterface child;

So, in this class we have merged the actual implementations of two other classes, Parent and Other without modifying either class. This is general multiple inheritance. In Java we needed to define and implement interfaces and use delegation to an object of one of the classes to achieve this.


Multiple inheritance is needed only rarely. The fact that it is a bit awkward to achieve in Java is not a disadvantage as it may discourage you from using it in those cases in which a better solution is available. However, you should be aware that extensions to Java are not necessary to achieve the use of most features that Java seems to lack. Rather the Java was a good, sound, and complete language design that supports the kinds of things that developers need. It takes skill, however, to see how to achieve some of the less used idioms such as multiple inheritance.


Multiple Inheritance in Java



线程我只写过继承Thread类的,后来知道java多线程有三种方式,今天首先比较一下常用的继承Thread类和实现Runnable接口的区别。               按着Ctrl键进入Threa...
  • xdd19910505
  • xdd19910505
  • 2016年02月24日 18:27
  • 5501

JAVA实验三 抽象类的继承和接口的实现 (多态)

题目要求: 1.编写一个ComputerAverage抽象类,类中有一个抽象方法求平均分average,可以有参数。定义Gymnastics类和School类,它们都是ComputerAverage...
  • PNAN222
  • PNAN222
  • 2016年04月14日 21:00
  • 2262


首先,类的多继承有哪些缺点那: 第一,如果一个类继承多个父类,如果父类中的方法名如果相同,那么就会产生歧义。 第二,如果父类中的方法同名,子类中没有覆盖,同样会产生上面的错误。 所以,java中就没有...
  • fengzijinliang
  • fengzijinliang
  • 2016年05月17日 21:12
  • 2660


程序员讨厌没有价值的任务 大多数程序员,据我所知,越是优秀,越是讨厌没有价值的任务。 寻找其工作的价值 这些年来,我看到很多颇有成绩的软件开发人员转行去了管理岗位,或者其他完全不同的职业。有...
  • yuan_chongjie
  • yuan_chongjie
  • 2015年03月20日 21:03
  • 261


框架整体介绍: 对此框架有兴趣或想参与开发的请加QQ群:255195191 以下...
  • flyxxxxx
  • flyxxxxx
  • 2017年07月26日 18:39
  • 138

IT 行业加班到底有没有价值?

众所周知,说到 IT 行业,大家的第一印象都是「加班严重」,不得不说,加班确实是 IT 行业潜规则了,IT 行业也被冠以「月薪高,时薪低」的美名。之前网上还流行这么一个段子:说一小伙去面试,面试官问到...
  • googdev
  • googdev
  • 2017年07月18日 14:02
  • 8463

IT 行业加班到底有没有价值?

众所周知,说到 IT 行业,大家的第一印象都是「加班严重」,不得不说,加班确实是 IT 行业潜规则了,IT 行业也被冠以「月薪高,时薪低」的美名。之前网上还流行这么一个段子:说一小伙去面试,面试官问到...
  • qq_35792598
  • qq_35792598
  • 2017年07月18日 16:04
  • 429


  面试是个双向选择的过程,公司在考察你的时候,也是你考察公司的机会,然而总有这样那样的理由导致在面试时对公司的印象分就大减。遇到下面这六种情况,别想太多,就算给了offer这种公司也不能去! ...
  • job51BBS
  • job51BBS
  • 2016年12月08日 08:52
  • 230


英文原文:Software Developers Hate Worthless Tasks   大多数程序员,据我所知,越是优秀,越是讨厌没有价值的任务。   寻找其工作的价值   这些年来,...
  • aerchi
  • aerchi
  • 2015年03月27日 09:55
  • 629

IT 行业加班到底有没有价值?

众所周知,说到 IT 行业,大家的第一印象都是「加班严重」,不得不说,加班确实是 IT 行业潜规则了,IT 行业也被冠以「月薪高,时薪低」的美名。之前网上还流行这么一个段子: 说一小伙去面试,面...
  • qq_27682041
  • qq_27682041
  • 2017年07月19日 14:11
  • 160