VBA使用Implements实现自定义类时如何统一存放公共代码
VBA/VB6 接口实现场景下的公共代码复用方案
VBA/VB6 仅支持接口抽象(Implements 语法),不支持类的实现继承,接口本身不能存放可执行的公共逻辑,要消除实现类的重复代码,最通用的方案是组合+委托模式,这也是VB系语言无继承环境下的标准代码复用实践。
实现步骤
1. 抽离公共逻辑到独立基类
新建一个普通类cTemplateBase,把所有实现类中完全重复的字段、属性、方法逻辑全部搬到这个类里,不需要实现任何接口,只做公共逻辑的容器:
' cTemplateBase 类代码 Option Explicit ' 原来每个实现类都重复声明的字段,统一放到这里 Private pParent As cMasterClass Private pName As String ' 原来重复的Init逻辑 Public Sub Init(Parent As cMasterClass, Name As String) Set pParent = Parent pName = Name End Sub ' 原来重复的Name属性逻辑 Public Property Get Name() As String Name = pName End Property ' 原来重复的Parent属性逻辑 Public Property Get Parent() As cMasterClass Set Parent = pParent End Property
2. 改造业务实现类,移除重复代码
所有实现cTemplateClass的业务类(cMyClass1、cMyClass2等),不再重复声明公共字段、编写公共逻辑,只需要在内部持有一个cTemplateBase的实例,将接口中公共成员的调用转发给这个实例处理,仅保留自身差异化的逻辑实现。
改造后的cMyClass1代码:
' cMyClass1 类代码 Option Explicit Implements cTemplateClass ' 持有公共逻辑类实例 Private mBase As cTemplateBase Private Sub Class_Initialize() Set mBase = New cTemplateBase End Sub ' 差异化逻辑,保留原有实现 Private Property Get cTemplateClass_SomeProperty() As String cTemplateClass_SomeProperty = "Some String from MyClass 1" End Property ' 以下公共逻辑全部委托给mBase处理,无需编写重复业务代码 Private Property Get cTemplateClass_Name() As String cTemplateClass_Name = mBase.Name End Property Private Property Get cTemplateClass_Parent() As cMasterClass Set cTemplateClass_Parent = mBase.Parent End Property Private Sub cTemplateClass_Init(Parent As cMasterClass, Name As String) mBase.Init Parent, Name End Sub
cMyClass2的改造逻辑完全一致,仅需要修改cTemplateClass_SomeProperty的返回值为"Some String from MyClass 2"即可。
方案说明
- 原有代码完全兼容:
cMasterClass和标准模块的Demo过程不需要做任何修改,运行结果和改造前完全一致。 - 维护成本大幅降低:后续如果需要修改
Init、Name、Parent的逻辑,只需要修改cTemplateBase一处代码,所有实现类自动生效,不需要逐个类调整。 - 灵活度高:如果后续接口新增了成员,通用逻辑就加到
cTemplateBase里,各实现类加一行委托调用即可;差异化逻辑直接在对应实现类编写,不会互相影响。 - 语言限制说明:受VBA语法约束,每个接口实现类必须显式写出所有接口成员的定义,无法完全消除转发的几行样板代码,但核心业务逻辑已经100%复用,是该语言环境下的最优解。
如果后续公共逻辑需要调用各实现类独有的成员,只需要在cTemplateBase的对应方法中增加参数传入差异化值,或者定义轻量的回调接口即可,不需要改动整体结构。
内容的提问来源于stack exchange,提问作者chris neilsen
相关产品推荐
相关产品推荐

