给出的大多数答案似乎都假设我们希望继承的所有类都是由我们定义的。
但是,如果我们没有定义其中一个类,即我们无法更改其中一个类继承自什么,因此无法使用已接受的答案,那么会发生什么?
那么答案取决于我们是否至少定义了一个类。A
即在我们想要继承的类列表中存在一个类,它A
是由我们创建的。
除了已经接受的答案之外,我还提出了这个多重继承问题的另外 3 个实例以及每个实例的可能解决方案。
继承类型 1
好吧,假设您想要一个类C
来扩展类,A
并且B
,哪里B
是在其他地方定义的类,但A
由我们定义。我们可以做的就是把它A
变成一个接口,然后类C
可以A
在扩展的同时实现B
。
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
最后,还有一种情况是你只有一堆类要继承,但它们都不是你定义的。这有点棘手,但可以通过使用委托来实现。委托允许一个类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
包含我们想要继承的类的公共方法的类?这样做是为了减少耦合。我们不希望类过去A
必须过多地依赖于类A
(因为类往往会发生很多变化),而是要依赖于接口中给出的承诺A
。