我正在使用Java中的某个API库。它有一个基类A,以及B和C,它们都扩展了A. B& C提供类似但不同的功能,所有三个类都在库中。
public abstract class A
{
virtual foo();
}
public class B extends A {}
public class C extends A {}
如何在班上获得A
,B
和C
的元素?如果我使用接口来实现类,则会有很多重复的代码,内部类将不允许我覆盖现有方法,以便A
,B
和{{1}的调用接口保留。
如何在Java中实现多重继承?
编辑: 感谢编辑George,现在更清楚了,忘记提及一个关键要求:我的类必须以A为基础,以便可以通过平台API进行管理。
答案 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)。如果您遵守这些限制,这将为您开启面向对象编程的新水平。