我有一个抽象基类T
,其中A
和B
类继承。我现在有一个操作(在T
上),需要在A
和B
中稍微不同的实现,但大多数代码是相同的。让我举个例子:有两种方法可以实现.Clone
方法:
Public MustInherit Class T
Protected MustInherit Function _DoClone() As T
Public Function Clone() As T
Dim clone = Me._DoClone() ' do the subclass-specific stuff '
... ' do the shared stuff '
End Function
End Class
Public Class A
Inherits T
Protected Overrides Function _DoClone() As T
... ' do the subclass-specific stuff '
End Function
End Class
或
Public MustInherit Class T
Protected Sub _DoClone(clone As T)
... ' do the shared stuff '
End Function
Public MustInherit Function Clone() As T
End Class
Public Class A
Inherits T
Public Overrides Function Clone() As T
Dim clone = ... ' do the subclass-specific stuff '
Me._DoClone(clone)
End Function
End Class
(示例在VB.NET中,但同样的问题适用于C#,Java等)
我的问题:
_Do...
事物),是否有完善的命名约定?答案 0 :(得分:7)
看起来像Template method pattern:
模板方法用于:
- 让子类实现(通过方法覆盖)可以改变的行为
- 避免代码中的重复:您在算法中查找通用代码,并在子类中实现变体
- 允许在什么时候控制子类化。
答案 1 :(得分:2)
如果克隆工作需要基类中的代码,则第一个选项是正确的。第二个选项允许您在不调用基类中的代码的情况下实现Clone方法。
如果不需要基类中的代码,则第二个选项是正确的。第一个选项不允许您在不调用基类中的代码的情况下实现Clone方法。
答案 2 :(得分:1)
一般来说,我会使用第一种方法,因为它更简单。但是,在某些情况下,第二个是必需的。
请注意,以对象克隆为例可能不是最佳选择。克隆的特殊之处在于返回的对象必须与要克隆的对象的类型相同,即使重写的方法属于基类型。
假设您有一个继承自A的B类,您可以这样做:
A a = new B();
B b = (B)a.Clone();
使用第一种方法,克隆对象必须由A创建,但类型必须是B类型。通常,您将使用object.MemberwiseClone()
来实现此目的,但这会阻止您替换只读字段因为这只能在构造函数中完成(例如克隆一个不能由克隆和原始对象共享的List)。
答案 3 :(得分:1)
第一个选项是公平的,其中有一个特定的工作,你知道在派生类中会有所不同。也许你想拥有
Public MustInherit Class T
Protected MustInherit Function Clone() As T
Public Function CloneAdjusted() As T
Dim clone = Me.DoClone()
' Adjust clone '
End Function
End Class
Public Class A
Inherits T
Protected Overrides Function Clone() As T
' Make exact copy of A '
End Function
End Class
如果您只是想要克隆任何旧的T但想要在子类中进行小的调整,那么第二种方法会更合适。但在这种情况下,请覆盖Clone方法,而不是使用新名称创建新方法。例如
Public MustInherit Class T
Public Overridable Function Clone() As T
Dim clone = ' Clone a T here '
End Function
End Class
Public Class A
Inherits T
Public Overrides Function Clone() As T
' Any pre-clone work '
T obj = MyBase.Clone()
' Any post-clone work '
End Function
End Class
不,这对克隆人来说并没有完全合理意义,当你看到它时,因为你将从基础克隆中获得一个T,并将其转换为A并不是全部容易。
您可以考虑其他几种选择。
一个是助手类。您可能希望将公共代码移到静态类的静态方法中,以避免重复,而不是在T中包含任何代码。
另一个是拥有ICloner接口,T了解合同但A和B理解实施,例如
Public MustInherit Class T
Protected ICloner Cloner
Public Overridable Function Clone() As T
' Common Code '
Dim clone = Cloner.GetClone()
' More Common Code '
End Function
End Class
Public Class A Inherits T
Public Sub New()
Cloner = New ACloner(Me)
End Sub
End Class
足够困惑?