给出的大多数答案似乎都假设我们希望继承的所有类都是由我们定义的。
但是如果我们没有定义其中一个类,即我们无法更改其中一个类继承自什么,因此无法使用已接受的答案,那么会发生什么?
答案取决于我们是否至少定义了一个类。即在我们想要继承的类列表中存在一个类A,其中A是我们创建的。
除了已经接受的答案之外,我还提出了多继承问题的另外 3 个实例以及每个实例的可能解决方案。
继承类型 1
好吧,假设你想要一个类C 来扩展类A 和B,其中B 是在其他地方定义的类,但A 是由我们定义的。我们可以做的是把A变成一个接口,然后类C可以在扩展B的同时实现A。
class A {}
class B {} // Some external class
class C {}
变成
interface A {}
class AImpl implements A {}
class B {} // Some external class
class C extends B implements A
继承类型2
现在假设你有两个以上的类要继承,同样的想法仍然成立——除了一个类之外的所有类都必须由我们定义。假设我们希望类A 继承自以下类,B、C、...X 其中X 是我们外部的类,即在其他地方定义的类。我们采用相同的想法,将除最后一个以外的所有其他类转换为接口,然后我们就可以拥有:
interface B {}
class BImpl implements B {}
interface C {}
class CImpl implements C {}
...
class X {}
class A extends X implements B, C, ...
继承类型 3
最后,还有一种情况是你只有一堆类要继承,但它们都不是你定义的。这有点棘手,但可以通过使用delegation 来实现。委托允许类A 伪装成其他类B,但是任何对A 的调用对B 中定义的某些公共方法,实际上是委托对B 类型对象的调用,结果是回来。这使得A 类成为我所说的Fat class
这有什么帮助?
嗯,很简单。您创建一个接口,指定您想要使用的外部类中的公共方法,以及您正在创建的新类中的方法,然后您让新类实现该接口。这可能听起来令人困惑,所以让我解释一下。
最初我们有以下外部类 B、C、D、...、X,我们希望我们的新类 A 继承自所有这些类。
class B {
public void foo() {}
}
class C {
public void bar() {}
}
class D {
public void fooFoo() {}
}
...
class X {
public String fooBar() {}
}
接下来我们创建一个接口A,它公开了之前在类A中的公共方法以及来自上述类的公共方法
interface A {
void doSomething(); // previously defined in A
String fooBar(); // from class X
void fooFoo(); // from class D
void bar(); // from class C
void foo(); // from class B
}
最后,我们创建一个类AImpl,它实现了接口A。
class AImpl implements A {
// It needs instances of the other classes, so those should be
// part of the constructor
public AImpl(B b, C c, D d, X x) {}
... // define the methods within the interface
}
你有它!这是一种伪继承,因为 A 类型的对象不是我们开始使用的任何外部类的严格后代,而是公开了一个接口,该接口定义了与这些类中相同的方法。
您可能会问,为什么我们不只是创建一个定义我们想要使用的方法的类,而不是定义一个接口。即为什么我们没有一个类A,它包含我们想要继承的类的公共方法?这样做是为了减少coupling。我们不希望使用A 的类不得不过度依赖A 类(因为类往往会发生很大变化),而是依赖于接口A 中给出的承诺。