我有一個關於如何在不允許多重繼承的語言中處理以下場景的理論問題。沒有多重繼承且沒有代碼複製的多重繼承
可以想象我有一個基類富並從中我希望創建三個子類:
- 類酒吧繼承富和實現的功能「A」
- 類Baz繼承Foo並實現功能「B」
- 類Qux繼承美孚和實現的功能「A」和「B」
想象的是,代碼來實現的功能「A」和「B」始終是相同的。有沒有辦法爲「A」和「B」編寫代碼一次,然後讓適當的類應用(或「繼承」)它?
我有一個關於如何在不允許多重繼承的語言中處理以下場景的理論問題。沒有多重繼承且沒有代碼複製的多重繼承
可以想象我有一個基類富並從中我希望創建三個子類:
想象的是,代碼來實現的功能「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
由組成的實現。
這是語言提供的特徵實現(在這裏: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() {}
}
這個更通用的術語是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 {
...
}
任何特定語言? Java的? C#?還有別的嗎? – Tudor
爲什麼你不能在你的FOO類中實現相同的功能,只是將A/B標記爲虛擬/可重寫? – YavgenyP
@Tudor在C#中思考,但任何不允許多繼承的OOP語言都可以。 –