2011-06-07 40 views
4

我有A類實現IA。
現在我需要創建類B,也應該實現IA。 B類具有A類實例作爲成員。執行接口使用成員作爲執行者

有什麼方法可以定義A的實例在類B中實現IA嗎?

interfase IA { 
    void method1(); 
    void method2(); 
    . 
    . 
    . 
    . 
    void methodN(); 
} 

class A:IA { 
    public void method1(){} 
    public void method2(){} 
    . 
    . 
    . 
    . 
    public void methodN(){} 
} 

class B:IA { 
    private IA m_a; 
    public B(IA a) { 
     m_a=a; 
    } 

    //Instead all of this I am looking of a way to define that m_a is the implement to IA of B 
    public void method1(){ use of a.method1 } 
    public void method2(){ use of a.method2 } 
    . 
    . 
    . 
    . 
    public void methodN(){ use of a.methodN } 
} 
+1

您可以從A繼承B. – 2011-06-07 08:08:40

+0

@Alex Aza:查看我寫給@DanielB的內容。 – Naor 2011-06-07 08:15:08

+0

完美有效的功能請求,德爾福有這樣的東西。但是C#沒有。我不知道這種模式是否很常見。 – 2011-06-07 08:23:42

回答

1

如果B是真的要實現IA,然後B必須重新定義每個接口方法一個接一個,即使每個實施是簡單地的執行情況的電話封裝成A成員。

然而,有一個偷懶的辦法,可以防止你所有這些繁瑣的東西,這幾乎可以被認爲是相同的,從實用的角度來看:

class Program 
{ 
    static void Main(string[] args) 
    { 
     CatOwner Bob = new CatOwner(); 
     Console.WriteLine(((Cat)Bob).Cry); 
     Console.ReadKey(); 
    } 
} 

interface ICry 
{ 
    string Cry { get; } 
} 

class Cat : ICry 
{ 
    public string Cry { get { return "Meow !"; } } 
} 

class CatOwner 
{ 
    private Cat _MyCat; 

    public CatOwner() 
    { 
     _MyCat = new Cat(); 
    } 

    public static implicit operator Cat(CatOwner po) 
    { 
     return po._MyCat; 
    } 
} 

CatOwner並沒有真正落實Cry因爲貓的主人不是那種喵喵的人:他的貓是。但是作爲一個近似值,我們可以考慮通過要求貓主人哭泣,我們當然意味着這個需求實際上是針對他的貓,而不是主人本身。然後我們「把貓主人扔給他的貓」,然後我們可以讓他成爲Cry

這很有趣,不是嗎? :-)

編輯:

也就是說,Magnus的答案是非常值得考慮恕我直言。考慮到語義語境,如果傳遞一個成員是很好的,那麼它看起來更合乎邏輯,更乾淨。如果B只是一種增強變種A,它不能被繼承(密封),或者在這樣一個特定的上下文中,我的解決方案可能仍然很有趣......真的取決於上下文和語義約束...

1

從A得到B就是你所需要的。

class B:A { 

    public B() { 

    } 
} 
+0

我不能從A派生出來,因爲A並不總是IA的實現。後來我會有C來實現IA,我希望C的實例將取代B的IA實現。 – Naor 2011-06-07 08:12:12

+1

然後,您可以創建一個實現IA並從中派生的抽象類。如果你的界面非常複雜,並且每個類都有每個屬性/函數的獨特實現,那麼你必須爲每個實現這個界面的類編寫它。 – DanielB 2011-06-07 08:15:20

+0

在我的現實世界中B已經從某人繼承的問題。 – Naor 2011-06-07 08:20:59

1

你基本上有兩種選擇:從A繼承或封裝A。這基本上是兩種設計模式之間的區別:encapsulationinheritance

+0

我知道我有的選擇 - 我正在尋找一些我不知道的東西來保存許多代碼行。 – Naor 2011-06-07 08:16:23

0

不確定,但你爲什麼要從IA繼承B類?您已經有B類中的對象A的實例,您可以使用它...

+0

我沒有B類中的對象A的實例。我有一些實現IA的實例。 – Naor 2011-06-07 08:17:17

+0

雅我知道你是以IA作爲參數..但假設如果A實現IA你會傳遞A,如果C實現IA你會傳遞C,所以你訪問那些實現的方法吧?/ – BreakHead 2011-06-07 08:25:59

+0

不完全是。在運行時我可以調用這個方法:public ChangeIA(IA ia){m_a = ia;}並且實現將改變。 – Naor 2011-06-07 08:27:38

3

不是,您可能要定義某種接口,返回IA成員,如Enumerable/Enumerator模式。

public interface IB 
{ 
    public IA Item { get; } 
} 

然後B可以簡單地返回你存儲在其中的實例。

public class B : IB 
{ 
    public IA Item { get; private set; } 
} 

A甚至可以實現IB

public class A : IA, IB 
{ 
    public void Method1(); 
    //... 
    public void MethodN(); 

    IA IB.Item 
    { 
     get 
     { 
      return this; 
     } 
    } 
} 
+0

A不應該知道B. B必須實現IA,因爲某個地方我有一個只接受IA的模塊。但是B實際上擁有比IA允許的更多的數據。 – Naor 2011-06-07 08:20:00

+0

你有沒有考慮過使用動態對象類? http://winterdom.com/2009/05/dynamicobject-in-c-40 – Philipp 2011-06-07 08:29:51

0

如何在屬性揭露 「執行者」,而不是說明B implementering接口。

class B 
{ 
    public IA Implementer {get; private set;} 
    public B(IA a) 
    { 
     Implementer = a; 
    } 
} 
+0

B必須實現IA,因爲某處我有一個只接受IA的模塊。但是B實際上擁有比IA允許的更多的數據。 – Naor 2011-06-07 08:22:00

+0

然後,你只需發送b.Implementer到你的模塊,而不是如果B – Magnus 2011-06-07 08:23:59

+0

瞭解你說的,但這是不可能的模塊內置的方式.. – Naor 2011-06-07 09:57:46

0

看着從設計的角度來看你的問題,它是一個完全有效的問題(在一個更復雜的現實生活中的情況),這將是很好的通過只是說成員M_A是節省了大量的代碼行實現B中所有IA接口的一個。

我不完全同意B從A繼承B的建議:在現實生活中,B可以繼承另一個不相關的類,或者說你正在實現IC和ID,並且具有成員m_c和m_d可以很好地指出將C的實現指向m_c並將ID的實現指向m_d..etc 2-用inheritanc替換聚合e通常是一個糟糕的設計。

好主意,但..

+0

對我來說,它看起來像是必須的東西..告訴某種程度上m_a是IA的植入,如果在B中對IA的實現有「覆蓋」 - 它將取代m_a的實現或類似的東西。 – Naor 2011-06-07 08:24:31