以下类在 ASP.NET 应用程序中用于从数据库结果集中读取货币并将其相加(例如,显示以美元为单位的总计加上以英镑为单位的显示总计)。它的工作原理如下:
- 读取货币 ID 值
- 如果货币 ID 已存在,请增加该货币的总数
- 如果货币 ID 不存在,请将其及其值添加到列表中
- 下一步
使用 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/