2012-05-27 113 views
5

我有一個關於如何在不允許多重繼承的語言中處理以下場景的理論問題。沒有多重繼承且沒有代碼複製的多重繼承

可以想象我有一個基類並從中我希望創建三個子類:

  • 酒吧繼承和實現的功能「A」
  • Baz繼承Foo並實現功能「B」
  • Qux繼承美孚和實現的功能「A」和「B」

想象的是,代碼來實現的功能「A」和「B」始終是相同的。有沒有辦法爲「A」和「B」編寫代碼一次,然後讓適當的類應用(或「繼承」)它?

+0

任何特定語言? Java的? C#?還有別的嗎? – Tudor

+0

爲什麼你不能在你的FOO類中實現相同的功能,只是將A/B標記爲虛擬/可重寫? – YavgenyP

+0

@Tudor在C#中思考,但任何不允許多繼承的OOP語言都可以。 –

回答

3

那麼我可以看到你在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功能也是AB由組成的實現。

1

這是語言提供的特徵實現(在這裏:):

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() {} 
} 
3

這個更通用的術語是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 { 
    ... 
} 
1

有幾種方法可以做到這一點。更具體地說,如果我們暫時放棄繼承方面,有一些方法可以將相同的功能單元引入到不同的類中,而只需編寫一次單元。

好吧,我AOP框架,它們存在多種語言(C#和Java有幾個)。 AOP框架基本上允許您在整個繼承結構中將自包含的功能添加到不同的類中。

對於C#,你有PostSharp,對於Java你有AspectJ,等等。

許多AOP框架允許「劫持」或「覆蓋」方法調用而不使用繼承。