3

以下类在 ASP.NET 应用程序中用于从数据库结果集中读取货币并将它们相加(例如以美元显示总计加上以 GB 磅显示总计)。它以下列方式工作:

  1. 读取货币 ID 值
  2. 如果货币 ID 已存在,则增加该货币的总数
  3. 如果货币 ID 不存在,则将其与其值一起添加到列表中
  4. 下一个

使用该CurrencyID属性作为每种独特货币之间的区别,效果很好。但是,现在很明显,IsoCurrencySymbol默认情况下每种货币也是唯一的,因此CurrencyID实际上并不需要。

所以...我想知道是否可以从此类继承并删除对 的任何引用CurrencyID,因此改为CompareTo使用该方法IsoCurrencySymbol

诀窍是保留现有的类,因为它被广泛使用,但引入一个不需要的修改版本CurrencyID。请问这样可以吗?

<Serializable()> _
Public Class CurrencyCounter

    <Serializable()> _
    Private Class CurrencyType
        Implements IComparable

        Public IsoCurrencySymbol As String
        Public CurrencySymbol As String
        Public CurrencyID As Int16
        Public Amount As Decimal

        Public Function CompareTo(obj As Object) As Integer Implements System.IComparable.CompareTo
            If Not TypeOf (obj) Is CurrencyType Then
                Throw New ArgumentException("Object is not a currency type")
            Else
                Dim c2 As CurrencyType = CType(obj, CurrencyType)
                Return Me.CurrencyID.CompareTo(c2.CurrencyID)
            End If
        End Function

    End Class

    Private _Currencies As List(Of CurrencyType)

    Public Sub New()
        _Currencies = New List(Of CurrencyType)
    End Sub

    Private Sub AddStructToList(CurrencyID As Integer, IsoCurrencySymbol As String, CurrencySymbol As String, Amount As Decimal)
        If IsoCurrencySymbol <> String.Empty AndAlso Amount > 0 Then
            Dim s As New CurrencyType
            s.CurrencyID = CurrencyID
            s.IsoCurrencySymbol = IsoCurrencySymbol
            s.CurrencySymbol = CurrencySymbol
            s.Amount = Amount
            _Currencies.Add(s)
        End If
    End Sub

    Public Sub Add(CurrencyID As Integer, IsoCurrencySymbol As String, CurrencySymbol As String, Amount As Decimal)
        Dim ct As CurrencyType = _Currencies.Find(Function(obj) obj.CurrencyID = CurrencyID)
        If ct IsNot Nothing Then
            ct.Amount += Amount
        Else
            AddStructToList(CurrencyID, IsoCurrencySymbol, CurrencySymbol, Amount)
        End If
    End Sub

    Public Sub Clear()
        _Currencies.Clear()
    End Sub

    Public Function Count() As Integer
        Return _Currencies.Count
    End Function

    Public Function RenderTotals() As String
        ' ...
    End Function

End Class
4

1 回答 1

4

不,你不能那样做。继承的全部意义在于确保所有派生类,如果没有别的,至少与它们的基类共享相同的公共接口。如果您要删除一个属性,那么它不共享相同的接口,因此不兼容并且不适合继承。

如果你不能说派生类是基类的一种类型,那么你就不能使用继承。例如,我可以说汽车是一种交通工具,因此,如果我有一个汽车类,我可以让它从一个交通工具类继承。然而,我不能说昆虫是一种交通工具。因此,即使它们有大部分共同点,我也不能让昆虫类继承自车辆类。

此限制的原因是因为继承允许您将对象视为基本类型(通过类型转换)。例如:

Public Sub AddPassengerToVehicle(v As Vehicle)
    v.Passengers.Add(New Passenger())
End Sub

' ...

Dim auto As New Automobile()
Dim bug As New Insect()
AddPassengerToVehicle(auto) ' Works because an automobile is a type vehicle (inherits from vehicle)
AddPassengerToVehicle(bug) ' Can't possibly work (nor should it)

因此,如果您需要有一个派生类来删除/隐藏其基类的成员之一,那么您就走错了方向。在这种情况下,您需要创建一个全新的类,该类恰好具有非常相似的接口,但与第一个类没有直接关系,例如:

Public Class Vehicle
    Public Property Passengers As List(Of Passenger)
    Public Property MaxSpeed As Integer

    Public Function SpeedIsTooFast(speed) As Boolean
        Return (speed > MaxSpeed)
    End Function
End Class

Public Class Insect
    Public Property MaxSpeed As Integer

    Public Function SpeedIsTooFast(speed) As Boolean
        Return (speed > MaxSpeed)
    End Function
End Class

如果您想共享功能,例如SpeedIsTooFast上面示例中方法中的逻辑,那么有几种不同的方法可以做到这一点。这首先是制作简单地调用另一个类的包装器方法,例如:

Public Class Insect
    Private _vehicle As New Vehicle()

    Public Property MaxSpeed() As Integer
        Get
            Return _vehicle.MaxSpeed
        End Get
        Set(value As Integer)
            _vehicle.MaxSpeed = value
        End Set
    End Property

    Public Function SpeedIsTooFast(speed) As Boolean
        Return _vehicle.SpeedIsTooFast(speed)
    End Function
End Class

如果你这样做,最好让两个类实现相同的公共接口,以便在必要时可以互换使用它们,例如:

Public Interface ISelfPoweredMovingThing
    Property MaxSpeed As Integer
    Function SpeedIsTooFast(speed As Integer) As Boolean
End Interface

另一种选择是将通用功能分解为第三个类,然后将该类用作其他两个类的基础,例如:

Public Class SelfPoweredMovingThing
    Public Property MaxSpeed As Integer

    Public Function SpeedIsTooFast(speed) As Boolean
        Return (speed > MaxSpeed)
    End Function
End Class

Public Class Vehicle
    Inherits SelfPoweredMovingThing

    Public Property Passengers As List(Of Passenger)
End Class

Public Class Insect
    Inherits SelfPoweredMovingThing

    ' Anything else specific only to insects...
End Class
于 2013-02-21T13:21:48.687 回答