【问题标题】:System.StackOverflowException when creating instance of class创建类实例时出现 System.StackOverflowException
【发布时间】:2017-12-12 01:43:02
【问题描述】:

我在创建 Vehicle 类的实例时收到 System.StackOverflowException。我相信它正在发生,因为我有一个对继承自 Vehicle 的 Car 类的对象引用,并且它陷入了无限循环。

Public Class Vehicle
   Public Car As New Car
End Class

Public Class Car
   Inherits Vehicle

   Public Sub doStuff()
      'does stuff
   End Sub
End Class

虽然这可能是不好的做法,但我将其结构如下,因为我需要能够从另一个文件访问 doStuff(),而不必创建 Car 的实例,如下所示:

'some other file
Public Class Foo
   Private Vehicle As New Vehicle
   Vehicle.Car.doStuff() 'this is what I am trying to accomplish
End Class

我还有其他方法可以做到这一点吗?

编辑:由于似乎有点混乱,我想澄清一下,我有多个继承自 Vehicle 的类(Car、Truck、Bike 等)。所有这些类都有自己独特的方法,但都需要使用 Vehicle 的一些方法和属性。使用virtual 并不是我想要的,因为我不需要覆盖任何方法。

【问题讨论】:

  • Vehicle 不应该实例化汽车类,它应该是相反的方式
  • 不知道doStuff() 做了什么,很难说,但是“我需要能够从另一个文件访问doStuff() 而不必创建Car 的实例”通常是通过将其设为Shared - 即Public Shared Sub doStuff() 来解决。然后,您可以直接从Foo 中的方法调用它:Car.doStuff()
  • 你不只是'有一个对 Car 类的对象引用`车辆 创建一个 new Car 实例并且 Car 继承自 Vehicle,因此无穷无尽循环:车辆->汽车->车辆...
  • @Plutonix 啊是的,这就是我的意思,抱歉措辞不正确。是否可以使 Car 实例不可继承,以免发生无限循环?还是我需要完全重新考虑我想要构建它的方式?
  • 继承不是这样工作的。您不需要 Vehicle 实例,只需要汽车或卡车实例。 Dim c = New Car() 然后 Car.Park()Truck.Honk 其中 Park 和 Honk 是 Vehicle 方法。由于 Car 继承自 Vehicle,所有基类方法都将可用(直接)

标签: .net vb.net inheritance


【解决方案1】:

好的,我认为这可能是对您为什么要派生类的误解。让我给你一个使用你的两个类的例子:

Public Class Vehicle
    Public Sub DoVehicleStuff()
        ' code here
    End Sub
    Public Overridable Sub OverridableVehicleStuff()
        'code here
    End Sub
End Class

Public Class Car
    Inherits Vehicle

    Public Sub DoCarStuff()
        'code here
    End Sub
    Public Overrides Sub OverridableVehicleStuff()
        'code here
    End Sub
End Class

好的,Vehicle 有两个功能 - 其中之一是“可覆盖”,这意味着它存在,但派生类可以覆盖它。然后,Car 继承自 Vehicle - 这意味着它获得相同的 DoVehicleStuff() 和 OverridableVehicleStuff()。但随后它添加了一个额外的函数 DoCarStuff() 并将 OverridableVehicleStuff 替换为它自己的函数版本。

综合起来,我们可以像这样使用类:

Dim myVehicle As Vehicle = New Vehicle()
myVehicle.DoVehicleStuff()
myVehicle.OverridableVehicleStuff() ' does the VEHICLE version of the function
'this will not compile: myVehicle.DoCarStuff() - because vehicles do not have that function.  It is in the car sub-class.

Dim myCarStoredInVehicle As Vehicle = New Car()
myCarStoredInVehicle.DoVehicleStuff() 'I can still use this function - because Car inherited it
myCarStoredInVehicle.OverridableVehicleStuff() 'this will do the CAR version of the function.
'this will not compile: myCarStoredInVehicle.DoCarStuff()

Dim myCar As Car = New Car()
myCar.DoVehicleStuff() 'I can still call this function.
myCar.DoCarStuff() 'and I can do the DoCarStuff() function, because the variable is a Car.

所以回答你的问题:doStuff() 是所有车辆需要的东西,还是只是汽车?如果这是所有车辆都需要以某种方式完成的事情,那么您需要编写一个可覆盖(或抽象)的函数。如果它是只有 Cars 使用的东西,那么您不能将 Vehicle 类实例用于您想要的。您需要以下选项之一:

  1. 将变量声明为 Car。
  2. 将变量声明为 Vehicle,但将其实例化为 New 车()。然后在需要使用时将变量转换为 (Car) DoStuff()。

编辑:糟糕,OP 询问的是 VB,而不是 C#。适当地编辑了代码。

【讨论】:

  • @Lews - 谢谢!我什至没有注意到这一点。我编辑了答案以将其更改为 vb.net
猜你喜欢
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
相关资源
最近更新 更多