我有一个关于如何用不允许多重继承的语言处理以下场景的理论问题。
想象一下,我有一个基类Foo,我希望从中创建三个子类:
- 类Bar继承Foo并实现功能“A”
- Baz类继承Foo并实现功能“B”
- Qux类继承Foo并实现功能“A”和“B”
想象一下实现功能“A”和“B”的代码总是相同的。有没有办法只为“A”和“B”编写一次代码,然后应用适当的类(或“继承”)它?
我有一个关于如何用不允许多重继承的语言处理以下场景的理论问题。
想象一下,我有一个基类Foo,我希望从中创建三个子类:
想象一下实现功能“A”和“B”的代码总是相同的。有没有办法只为“A”和“B”编写一次代码,然后应用适当的类(或“继承”)它?
好吧,我可以看到您在 C#/Java 中实现这一目标的唯一方法是通过组合。考虑一下:
class Foo {
}
interface A {
public void a();
}
interface B {
public void b();
}
class ImplA implements A {
@Override
public void a() {
System.out.println("a");
}
}
class ImplB implements B {
@Override
public void b() {
System.out.println("b");
}
}
class Bar extends Foo {
A a = new ImplA();
public void a() {
a.a();
}
}
class Baz extends Foo {
B b = new ImplB();
public void b() {
b.b();
}
}
class Qux extends Foo {
A a = new ImplA();
B b = new ImplB();
public void b() {
b.b();
}
public void a() {
a.a();
}
}
现在Qux
既有Foo
通过普通继承的功能,也有通过组合的A
实现B
。
更通用的术语是Mixin。一些语言提供开箱即用的支持,例如 Scala 和 D。不过,有多种方法可以在其他语言中实现相同的结果。
在 C# 中创建伪混合的一种方法是使用空接口并为方法提供扩展方法。
interface A { }
static class AMixin {
public static void aFunc(this A inst) {
... //implementation to work for all A.
}
}
interface B { }
static class BMixin {
public static void bFunc(this B inst) {
...
}
}
class Qux : Foo, A, B {
...
}
这在提供特征的语言中是可以实现的(这里:scala):
class Foo {
def fooM() {}
}
trait A {
def aFunc() {}
}
trait B {
def bFunc() {}
}
class Bar extends Foo with A {}
class Baz extends Foo with B {}
class Qux extends Foo with A with B {}
因为 Scala 在 Java 之上运行(既没有多重继承也没有特征),所以它被翻译成这样的东西(简化)——这可能是一个提示如何在 Java/C# 中手动实现它:
class Foo {
}
interface A {
void aFunc();
}
interface B {
void bFunc();
}
class Bar extends Foo implements A {
public void aFunc() {
$A.aFunc();
}
}
class Baz extends Foo implements B {
public void bFunc() {
$B.bFunc();
}
}
class Qux extends Foo implements A, B {
public void aFunc() {
$A.aFunc();
}
public void bFunc() {
$B.bFunc();
}
}
class $A {
public static void aFunc() {}
}
class $B {
public static void bFunc() {}
}