2

我试图在 .NET 中更好地理解继承/接口/实现。

我有一个定义如下(有点)的类:

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

问题是,[Step] 只是一个虚拟的基类。[Step]有5种不同的具体实现。为了让事情更复杂一点,[Step] 有 3 个 DIRECT 实现,其中 2 个是虚拟的。这 2 个中的每一个都有 2 个子类,它们将具体实现 [Step]。

所以,它看起来是这样的:

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

因此,SubStepB、SubStepAA、SubStepAB、SubStepCA 和 SubStepCB 是具体的实现。

我希望 ANY Step 做几件事,例如 Clone()。

因此,我尝试在 Step 中声明以下内容:

Public MustOverride Function Clone() As Step

问题是,当我尝试在 SubStepAA 中实现它时,我无法声明以下内容:

Public Overrides Function Clone() As SubStepAA

如果我这样做,我会收到返回类型不同的错误。

每当我克隆一个具体的子类时,是否只使用 DirectCast 调用的解决方案?这看起来很奇怪,也很不满意。这似乎也是错误的。我的意思是,如果我克隆一个 SubStepAA 对象,我想取回一个 SubStepAA 类型的对象。

一定有办法做到这一点,对吧?我的意思是,我想我可以按照需要的方式声明每个类,但是必须编写 5 个不同的 Clone() 方法似乎也是错误的,这些方法只是碰巧以(基本上)相同的方式工作(创建一个深拷贝被引用的对象)。

我已经研究过使用接口声明,但这似乎受到相同类型不匹配错误的影响。

请告诉我,我只是缺少一些基本的东西!

谢谢!

顺便说一句,我一直在做一些阅读,我意识到可能有更优化的方法来进行对象的深层复制(例如,通过序列化/反序列化),但我仍然对这个问题感兴趣,即使我选择使用不同的方法克隆对象。

4

1 回答 1

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

如果您这样做,您将拥有额外的抽象层,您可以将每个具体对象转换为 aStep(T)或 a Step。例如,您可以这样做:

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

但是,当然,这一切都引出了一个问题,是否值得所有这些复杂化?两个更简单的解决方案是在每个派生类上独立实现接口(从而放弃从基类调用克隆的能力),或者按照您的第一个想法,让Clone方法始终返回基类型。

于 2012-12-28T16:25:26.353 回答