2014-02-20 52 views
1

昨天我詢問this question,但我認爲目前還不清楚我主要關心的是什麼。在C++中,我們擁有私有繼承和多重繼承,這使我們可以通過繼承聲明這些方法的類來爲類添加私有方法。也就是說,如果有一類在C#中通過繼承向類中添加私有方法

class B { 
public: 
    virtual void doMethodB(); 
}; 

和一類

class A : private B { 
    virtual int doMethodA(); 
}; 

doMethodB()可以從doMethodA()中被調用,而不是從外部訪問。

現在,我想在C#中模仿這種行爲。沒有多重或私人繼承。就知道了,我能想到的四種方式來實現類似的財產以後,但仍然有嚴重的缺陷:

首先:使用interface,即

interface IB { 
    public void doMethodB(); 
}; 
class A : IB { 
    public void doMethodB(); 
    int doMethodA(); 
}; 

然而,我們這樣做的時候,doMethodB()public,並且必須執行每個類繼承IB

二:使用一個靜態方法

public static class B { 
    public static void doMethodB(); 
}; 

這樣一來,有僅需要一個實現,但該方法仍是公衆,不能侷限於某些類別。

第三:使用擴展方法,如that。然而,該方法在對象(即a.doMethodB())上而不是從「內部」上被稱爲

第四:構圖。

class A { 
    private B b; 
    public int doMethodA(); 
}; 

現在,B的方法可以被稱爲像b.doMethodB()只從A,但其他的問題現在就係列化,b == null

難道還有其他選擇嗎?如果不是,你會考慮哪一個是「最好」

+1

由於私有繼承基本上是遏制,爲什麼不簡單地擁有'B'的私有成員變量? –

+0

您可以使用受保護的方法。 –

回答

2

關於具有接口的「第一個」提議:您也可以顯式實現接口: 「實現接口的類可以顯式實現該接口的成員,當成員明確實現時,不能通過一個類實例,但只能通過一個接口實例。「 請參閱/源代碼:http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx

但是,我會選擇合成方法。 「青睞組成了繼承」,也看到Prefer composition over inheritance?

理想的情況下,由依賴注入,我會構造函數注入BA,這應該有助於減輕你的b == null關注。

注: 使用靜態方法/擴展方法(是一個靜態方法,也...),使單元測試A(分別爲僞造B)很辛苦,這就是爲什麼我會完全放棄這些解決方案。

編輯: 如果您不需要B.doMethodB任何人比其他A訪問,也可以使Babstract類和B.doMethodB一個protected方法。 但我一直在想,你已經知道;-) (由於測試問題,我仍然贊成組合繼承)。

+0

您的提案與'abstract'類聽起來很相像;我會試一試。它幾乎是*我所需要的,儘管沒有多重繼承,它只能用於基類,而不能用於例如。一個'Windows.Form'我想? – Matz

+0

正確,有單一的繼承,所以你不能有'A:B,Windows.Form'。但是,您可以擁有'B:Windows.Form'和'A:B'(從'Windows.Form'繼承的'B'繼承'A') – BatteryBackupUnit

1

我認爲你正在尋找的概念是protected訪問修飾符。這意味着只有B本身及其派生類可以訪問該方法,但其他類不能。

class B { 
    protected virtual void DoMethodB() {} 
} 

class A : B { 
    virtual void DoMethodA() { 
     DoMethodB(); 
    } 
} 

如果你願意,你可以進一步限制訪問protected internal這意味着該方法只能從組件內的派生類訪問。

另外,請注意虛擬方法的後果。如果沒有明確的需要使方法變爲虛擬的,則不應該將其標記爲虛擬的。

+0

這是不一樣的。在問題'B:doMethodB'是公開的,所以人們可以創建一個'B'的實例並調用'doMethodB'。在你的例子中,任何創建'B'實例的人都不能調用該方法,只有派生類可以。 – Sean

+0

@肖恩是的,但這無論如何都會與繼承的性質是「一種」關係相沖突。 – Georg

+1

*私有*繼承不是一種「是 - 一種」關係。 – Matz