2012-12-28 71 views
2

我試圖圍繞繼承/接口/實現在.NET中更好一點。通過多代VB.NET強制繼承

我有已定義如下(排序的)的一類:

Public Class Sheet 
    Property Name As String 
    Property Steps As List(Of [Step]) 
End Class 

事情是,[步驟]僅僅是一個虛擬的,基類。 [Step]有5種不同的具體實現。爲了讓事情更復雜一點,有[Step]的3個DIRECT實現,其中2個是虛擬的。其中每一個都有2個具體實現[步驟]的子類。

所以,這裏是它的外觀:

      Step 
     |-----------------|-----------------| 
     |     |     | 
    SubStepA   SubStepB   SubStepC 
    |----|----|       |----|----| 
    |   |       |   | 
SubStepAA SubStepAB     SubStepCA SubStepCB 

所以,SubStepB,SubStepAA,SubStepAB,SubStepCA和SubStepCB是具體實現。

有幾件事我想要任何一個步驟來做,比如Clone()。

所以,我想宣佈在步驟如下:

Public MustOverride Function Clone() As Step 

的問題是,當我試圖實現在SubStepAA,我不能聲明如下:

Public Overrides Function Clone() As SubStepAA 

如果我這樣做,我會得到一個返回類型不一樣的錯誤。

解決方法是在克隆具體子類時隨時使用DirectCast調用?這看起來很奇怪而且令人不滿。這也似乎是錯誤的。我的意思是,如果我克隆一個SubStepAA對象,我想獲取一個SubStepAA類型的對象。

有一種方法可以做到這一點,對吧?我的意思是,我想我可以按照它需要的方式聲明每個類,但是編寫5個不同的Clone()方法似乎也是錯誤的,這些方法只是以HAPPEN的方式(基本上)以相同的方式工作(創建深層副本被引用的對象)。

我已經看過使用接口聲明,但似乎遭受相同類型不匹配錯誤。

請告訴我,我只是缺少一些基本的東西!

謝謝!另外,我一直在做一些閱讀,並且我意識到可能有更多的優化方法來做對象的深層副本(例如,通過序列化/反序列化),但我仍然對這個問題感興趣,甚至如果我選擇使用不同的方法克隆對象。

回答

2

這可能不是正是你所希望的東西,但你可以通過使用一個通用的基本類型滿足您的所有需求,如:

Public MustInherit Class [Step](Of T) 
    Public MustOverride Function Clone() As T 
End Class 

Public Class StepA 
    Inherits [Step](Of StepA) 

    Public Overrides Function Clone() As StepA 
     ' ... 
    End Function 
End Class 

然而,然後,就沒有共同Step基地可用於所有派生類型的類。舉例來說,就沒有辦法做這樣的事情:

Dim s As [Step] = New StepA() 'Won't work because there is no Step type, only a generic Step(T) type 
Dim c As [Step] = s.Clone() 

但是,如果你需要有一個共同的基本類型一樣,你仍然可以做這樣的事情,儘管有一些額外的複雜性:

Public Interface ICloneable(Of T) 
    Function Clone() As T 
End Interface 

Public MustInherit Class [Step] 
    Implements ICloneable(Of [Step]) 

    Public MustOverride Function CloneBase() As [Step] Implements ICloneable(Of [Step]).Clone 
End Class 

Public MustInherit Class [Step](Of T As [Step]) 
    Inherits [Step] 

    Implements ICloneable(Of T) 

    Public Overrides Function CloneBase() As [Step] 
     Return Clone() 
    End Function 

    Public MustOverride Function Clone() As T Implements ICloneable(Of T).Clone 
End Class 

Public Class StepA 
    Inherits [Step](Of StepA) 

    Public Overrides Function Clone() As StepA 
     ' ... 
    End Function 
End Class 

如果你沒有這樣的說法,你將有一個抽象的附加層,在那裏你可以施放每個具體對象無論是作爲Step(T)或作爲Step。例如,你可以這樣做:

Dim s As [Step] = New StepA() 
Dim c As [Step] = s.CloneBase() 

但當然,這一切都提出了問題,是否值得所有這些併發症?兩個更簡單的解決方案將是在每個派生類上獨立實現接口(從而放棄從基類調用克隆的能力),或者按照第一個想法進行操作,並且只需要Clone方法返回基類型。

+0

你能解釋第二部分嗎?它看起來更像我想要使用的,但是當我執行「Public MustInherit類[Step](T作爲[Step])」時,我得到「太少類型參數」錯誤。它似乎正在尋找另一個「[Step]」課程。思考? – mbm29414

+0

HOLY COW,@Steven ...我必須在甚至想象之前再讀至少10次,我明白你在說什麼......感謝這樣一個真棒的答案! +1 !!!!! –

+0

@ mbm30075您使用的是什麼版本的Visual Studio?我只是複製並粘貼到VS 2005中,並且沒有任何變化,它工作得很好。但是,泛型在之前的版本中不可用。 –