asp.net - 继承一个类以删除属性并更改方法逻辑

标签 asp.net vb.net inheritance

以下类在 ASP.NET 应用程序中用于从数据库结果集中读取货币并将其相加(例如,显示以美元为单位的总计加上以英镑为单位的显示总计)。它的工作原理如下:

  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

最佳答案

不,你不能那样做。继承的全部意义在于确保所有派生类(如果没有别的)至少共享与其基类相同的公共(public)接口(interface)。如果您要删除某个属性,那么它不共享相同的接口(interface),因此不兼容,并且不是继承的候选者。

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

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

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)

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

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),以便您可以在必要时互换使用它们,例如:

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

关于asp.net - 继承一个类以删除属性并更改方法逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15001287/

相关文章:

c# - 在 .NET 中仅使用没有相应字段的属性的缺点?

vb.net - 从标题栏直观地删除/禁用关闭按钮 .NET

java - Java Netbeans 变量继承问题

c++ - 在 SWIG 中处理来自 self 的特殊实例的类继承

c# - ASP.net 在 XDocument 中创建 XLink 节点

mysql - 如何使用session获取当前用户的信息

c# - 保存/检索图像。 ASP.NET MVC

ASP.NET 如何反转列表数组

mysql - 使用vb.net一键更新和插入mysql记录

c# - 使用protobuf-net继承时如何选择字段编号?