如何在Java中实现多重继承

时间:2010-10-12 17:04:59

标签: java multiple-inheritance

我正在使用Java中的某个API库。它有一个基类A,以及B和C,它们都扩展了A. B& C提供类似但不同的功能,所有三个类都在库中。

public abstract class A
{
    virtual foo();
}

public class B extends A {}
public class C extends A {}

如何在班上获得ABC的元素?如果我使用接口来实现类,则会有很多重复的代码,内部类将不允许我覆盖现有方法,以便AB和{{1}的调用接口保留。

如何在Java中实现多重继承?

编辑: 感谢编辑George,现在更清楚了,忘记提及一个关键要求:我的类必须以A为基础,以便可以通过平台API进行管理。

6 个答案:

答案 0 :(得分:14)

总结一下,你有:

class A
{
    public void foo() {}
}

class B extends A
{
    public specificAMethod() {}
}

class C extends A
{
    public specificCMethod() {}
}

上述类位于您无法访问或修改的库中。 您希望在第三个类D中获得B和C的行为,就好像它可以写:

class D extends B, C
{
}

右?

如何使用B和C而不是继承?你真的需要继承吗?你想调用私人B和C方法吗?

class D
{

private B b;
private C c;
}

答案 1 :(得分:2)

如果采用“首选组合而不是继承”的一般方法,您可能会发现其中一个或两个类实际上不应该是“继承”。在这两种情况下,这些类都有严格的“is-a”关系吗?如果你可以大声说“Has-a”并且听起来不傻,你可能想要合成。

例如,如果你正在实施一副纸牌,那3个黑桃是一个3并且它是一个铲子,但你也可以把它想象成它有一个3并且它有一套西装(铲)。既然你可以这样想,你应该更喜欢has-a解释和使用组合。

尝试远离继承树而不是几个深层对象 - 如果您感觉到使用多重继承的愿望,请尝试解决它。这是Java类强迫您通过不提供功能来设计代码更具可读性的情况之一(但不可否认,当您真正想要它时,它不存在而且可能会受到伤害!某些级别的混合将是好的)。

答案 2 :(得分:0)

听起来你想要扩展A - 称之为D - 覆盖它的foo(),然后有新的子类E& F扩展D并添加自己的功能。

您可能会考虑提取常用接口并重用它们。具有重构功能的良好IDE将使其易于操作。

答案 3 :(得分:0)

Java中无法实现多类继承,但您可以对接口使用多重继承。使用Delegation pattern,您可以将其他几个类的行为合并为一个。

答案 4 :(得分:0)

COM中应用了完全不同的方法:所有对象都继承自IUnknown,它有一个可以转换为Java的方法:

Object queryInterface(Class<?> clazz)

此方法的最简单实现可以是:

if(clazz.isAssignableFrom(this.getClass()))
    return this;
else
    return null;

单继承不起作用,只需添加:

else if(class == SomeClass.class) {
    return something;
} else ...

通过这种方式,即使是最复杂的多重继承案例也可以解决,并且您可以完全控制返回的内容以及何时返回,因此您可以避免许多与C ++等语言的“经典”多重继承问题,例如fork-join问题。

答案 5 :(得分:0)

从Java 1.8开始,您可以使用具有默认方法的接口。它非常方便,我倾向于使用它。也支持Covariant return types。有一个fiew restricktions(见下文),但你不必自己实现继承,让编译器为你工作。

public interface A {
    default A foo() {
        return this;
    }
}

public interface B extends A {
    @Override
    default B foo() {
        return this;
    }
}

public interface C extends A {
    @Override
    default C foo() {
        return this;
    }
}

public interface D extends B, C {
    @Override
    // if the return type does not implement B and C
    // the comiler will throw an error here
    default D foo() { 
        return this;
    }
}

请注意,但请注意,由于其静态接口,您无法调用super.foo或定义字段或私有成员(直到Java 9)。如果您遵守这些限制,这将为您开启面向对象编程的新水平。