VBAinheritance通过build设,构造不工作?

我刚刚开始在VBA中使用类,我正在按照这里所述的“通过构造inheritance”方法。 我的例子使用了一个简单的类,它包含一个值(作为变体)和一个值types(作为一个string)。 我创build了一个子类,其中值types被设置为构造函数中的string。 这是我的代码:

接口类(IVal)

'IVal interface class (from https://www.theartofquantfinance.com/inheritance-by-construction-in-vba/) Option Explicit '----------------------------------- 'Accessor methods for ValType '----------------------------------- Public Property Get ValType() As String End Property Public Property Let ValType(ByVal RHS As String) End Property '----------------------------------- 'Accessor methods for Val '----------------------------------- Public Property Get Val() As Variant End Property Public Property Let Val(ByVal RHS As Variant) End Property 'Add other methods here as "Public Sub" 'ie 'Public Sub HonkHorn() 'End Sub 

基类(CBaseVal)

 'CBaseVal base class - implements IVal interface (from https://www.theartofquantfinance.com/inheritance-by-construction-in-vba/) Option Explicit Implements IVal '------------------------------ 'Private Fields '------------------------------ Private valType_ As String Private val_ As Variant '------------------------------ 'Constructors and destructors '------------------------------ Private Sub Class_Initialization() valType_ = "Base Val" val_ = Nothing End Sub '------------------------------ 'Class Properties And methods - public, visible to all modules 'These would be declared in the interface class '------------------------------ Public Property Get ValType() As String ValType = valType_ End Property Public Property Let ValType(ByVal RHS As String) valType_ = RHS End Property Public Property Get Val() As Variant Val = val_ End Property Public Property Let Val(ByVal RHS As Variant) val_ = RHS End Property 'Add additional class methods here 'eg 'Public Sub HonkHorn() ' MsgBox prompt:="Beep!!!" 'End Sub '------------------------------ 'Interface property and method implementation - private, only visible to this module 'Delegate interface properties and methods to this (base) class using "Me" '------------------------------ Private Property Let IVal_Val(ByVal RHS As Variant) Me.Val = RHS End Property Private Property Get IVal_Val() As Variant IVal_Val = Me.Val End Property Private Property Let IVal_ValType(ByVal RHS As String) Me.ValType = RHS End Property Private Property Get IVal_ValType() As String IVal_ValType = Me.ValType End Property 'End Property 'Add additional IF methods here 'ie 'Private Sub ICar_HonkHorn() ' Call Me.HonkHorn 'End Sub 

子类(CStringVal)

 'CStringVal class - implements IVal interface and delegates to CVal as appropriate (from https://www.theartofquantfinance.com/inheritance-by-construction-in-vba/) Option Explicit Implements IVal '------------------------------ 'Private Fields '------------------------------ Private baseVal_ As IVal 'contains an instance of the IVal class (why isn't this "As CBaseVal"?) '------------------------------ 'Constructors and destructors '------------------------------ Private Sub Class_Initialization() Set baseVal_ = New CBaseVal 'initialize private field of type "val class" baseVal_.ValType = "string" baseVal_.Val = Nothing End Sub '------------------------------ 'Class Properties And methods (here's where you over-ride the base class implementation) 'These would be declared in the base class and the interface implementation below will delegate to either here or base class '------------------------------ 'eg 'Public Sub HonkHorn() ' MsgBox prompt:="Beep!!!" 'End Sub '------------------------------ 'Interface property and method implementation - declared in base class and either: '=> most delegate to base class '=> some may override base class and delegate here '------------------------------ Private Property Let IVal_Val(ByVal RHS As Variant) baseVal_.Val = RHS 'Delegate to base class End Property Private Property Get IVal_Val() As Variant IVal_Val = baseVal_.Val End Property Private Property Let IVal_ValType(ByVal RHS As String) baseVal_.Val = RHS 'Delegate to base class End Property Private Property Get IVal_ValType() As String IVal_ValType = baseVal_.ValType 'Delegate to base class End Property 'Add additional interface methods here 'ie 'Private Sub ICar_HonkHorn() ' Call Me.HonkHorn 'Overrides base class implementation, delegates to class method above 'End Sub 

这里是我用来testing它的代码:

 Public Sub testStringValClass() Dim interfaceClassVal As IVal Dim baseClassVal As CBaseVal Dim stringClassVal As CStringVal Set interfaceClassVal = New IVal Set baseClassVal = New CBaseVal Set stringClassVal = New CStringVal a = interfaceClassVal.ValType b = baseClassVal.ValType c = stringClassVal.ValType End Sub 

第一个问题是一个编译错误,该行的“找不到方法或数据成员”

 c = stringClassVal.ValType 

如果我注释掉那行,代码就会运行,但是使用Watches,看起来valType_没有被设置为基类对象的“Base Val”,或者是string类对象的“string”。 此外,还有以下属性的“对象variables或带块variables未设置”错误:

 stringClassVal.IVal_Val stringClassVal.IVal_ValType 

我有点不知所措……我认为这很简单,就像拼写错误,但我找不到它。

这只是因为你的类CStringVal没有实现ValType属性。 好的,你实现了接口IVal的属性ValType ,而不是类本身的显式ValType

要访问接口的方法,你需要以某种方式cast你的对象转换为接口的types。 例如:

 Dim itf As IVal Dim stringClassVal As New CStringVal Set itf = stringClassVal '<-- casts the object to the interface's type ' and now: c = itf.ValType 

或者您可以使用定义的名称:

 c = stringClassVal.IVal_ValType 

但是请注意,您尚未初始化variables的字段(在获取者之前使用这些字母)。

是的,在VBA / VB6中的inheritance有点棘手,不是很自然。 当一个类实现一个接口时,接口的方法可以通过对接口的引用而不是实现者对象来访问,除非后者明确地重新定义了方法/属性

另外请注意,初始化val_ = Nothing是无用的,不知何故是错误的。 未初始化的Variant被创build为一个empty变体。 基本上没有用于对象,不用于基本variables(包括string)。

另外@TimWilliams说构造函数的名字是Class_Initialize而不是Class_Initialization