Первый вариант достаточно справедлив, когда есть конкретная работа, которая, как вы знаете, будет отличаться в разных производных классах. Возможно, вы хотите иметь
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
Достаточно смущен?