После повторного изучения у меня есть ответ, но он не совсем удовлетворителен.Как и в большинстве ООП в VBA, это предполагает использование соответствующего интерфейса, но тот факт, что каждый класс (и каждый интерфейс) должен идти в отдельном модуле класса, делает его довольно неуклюжим способом выполнения действий.Итак, вот что:
Скажем, у меня есть класс с именем MyClass (который я называл «C» выше, но сейчас я вызываю «MyClass», чтобы сделать это более понятным).
do будет определять интерфейс, который я на самом деле буду использовать в своем коде, который раскрывает только те вещи о MyClass, которые я хотел сделать действительно публичными.Скажем, этот код находится в модуле класса IMyClass:
Public Function calcSomething()
End Function
Public Function equal(cinst As IMyClass) As Boolean
End Function
Тогда у меня есть мой класс MyClass, определенный с помощью этого кода в модуле класса:
Implements IMyClass
Private hidden1_ As Double
Private hidden2_ As Double
Public Sub init(h1 As Double, h2 As Double)
hidden1_ = h1
hidden2_ = h2
End Sub
Public Function equalDef(hidden1 As Double, hidden2 As Double) As Boolean
equalDef = (hidden1_ = hidden1 And hidden2_ = hidden2)
End Function
Private Function IMyClass_calcSomething() As Variant
IMyClass_calcSomething = hidden1_ * hidden2_
End Function
Private Function IMyClass_equal(cinst As IMyClass) As Boolean
If TypeOf cinst Is MyClass Then
Dim asMyClass As MyClass
Set asMyClass = cinst
IMyClass_equal = asMyClass.equalDef(hidden1_, hidden2_)
End If
End Function
И вот некоторыекод, который будет идти в обычном модуле:
Public Function mkMyClass(h1 As Double, h2 As Double) As IMyClass
Dim ret As MyClass
Set ret = New MyClass
Call ret.init(h1, h2)
Set mkMyClass = ret
End Function
Public Sub useMyClass()
Dim mc1 As IMyClass
Set mc1 = mkMyClass(42, 99)
Dim mc2 As IMyClass
Set mc2 = mkMyClass(42, 99)
Dim mc3 As IMyClass
Set mc3 = mkMyClass(99, 42)
Debug.Print mc1.calcSomething
Debug.Print mc1.equal(mc2)
Debug.Print mc3.calcSomething
Debug.Print mc3.equal(mc2)
End Sub
В подпрограмме 'useMyClass' вы можете проверить, что различные переменные mc1, mc2 и mc3 не могут видеть 'init' или 'equalDef'методы MyClass.Они могут видеть только методы «calcSomething» и «равные», которые являются частью интерфейса.
Итак, вопрос официально, но неудовлетворительно ответил, я полагаю.По крайней мере, это дает мне возможность повторить: «ООП в VBA - это PITA (TM)» ...
Вот несколько связанных ответов на вопросы stackoverflow:
Наследование VBA, аналогsuper
Есть ли способ перегрузить процедуру конструктора / инициализации для класса в VBA?