防止将继承的对象传递给共享函数

时间:2012-10-31 12:35:51

标签: vb.net inheritance

我有一个非常人为的例子,我的业务对象如何加载他们的数据。但是,我想防止下面所示的情况。我知道这里有缺点,但它就是这样(到目前为止)!如何在不重构接口等的情况下实现这一目标?

Public Class Car

  Public Property Passengers As Integer

  Public Shared Sub Fill(c As Car, r As SqlDataReader)
    Passengers = r.GetInt32(0)
  End Sub

End Class

Public Class UsedCar
  Inherits Car

  Public Property PreviousOwner As String

  Public Shared Sub FillUsed(l As Limo, r As SqlDataReader)
    Passengers = r.GetInt32(0)
    PreviousOwner = r.GetString(1)
  End Sub

End Class

Public Sub CreateVehicles()

  Dim c As New Car()
  Car.FillWithStuff(c, GetSqlReader(carId))

  Dim l As New UsedCar()
  UsedCar.FillUsed(l, GetSqlReader(usedCarId)) 'Great
  Car.Fill(l, GetSqlReader(usedCarId)) 'No! << Stop this at once!
  UsedCar.Fill(l, GetSqlReader(usedCarId)) '<<< Even more wrong!

End Sub

2 个答案:

答案 0 :(得分:1)

除了抛出异常之外,没有办法要求它。例如:

Public Shared Sub FillWithStuff(c As Car)
    If Not (TypeOf c Is Car) Then
        Throw New Exception("Must be a Car")
    End If
    Passengers = 4
End Sub

但是,您提供的简化示例并未充分解释为什么在您的情况下,豪华轿车不是有效的汽车。事实上,如果它不是一辆有效的汽车,那么它不应该继承汽车。您的代码可能应该被重构,以便汽车和豪华轿车是两个不相关的类,它们共享相同的依赖性业务类以实现通用功能。

答案 1 :(得分:1)

使构造函数成为私有,并让各种Fill()方法实例化并返回一个全新的对象,或者您可以将Fill()代码移动到构造函数本身。由于您的方法与数据库结果紧密相关,另一种选择是将构造函数标记为“Friend”并将Fill()方法移动到与数据层一起使用的单独模块。

这里的目标是 only 创建汽车的方法是使用一个定义的工厂方法,该方法可以在编译时检查 相应的类型匹配。