在VB6下如何实现继承,重载和多态----DynamicClassFactory
  M9aMEIE19lAW 2023年11月02日 46 0


在VB6下如何实现继承,重载和多态----DynamicClassFactory (一)


[摘要]

   DynamicClassFactory ,一个支持在VB6里实现继承,多态,重载的库,目前,DynamicClassFactory还在开发中,预计月底出测试版,届时提供网友下载使用.本文仅仅介绍对属性继承的实现,下一篇将集中介绍函数的继承\多态\重载,敬请关注.


[正文]

//是不是在为VB6对继承支持得不好而发愁?是不是在为VB6没有重载而发愁?有类似疑惑的话,请继续阅读,DynamicClassFactory 将为您解开这些疑惑. 
'//有的时候,在编程时,老感觉某个控件的属性少了点什么,比如 Tag 属性为什么只有一个?其实我们只是在想记录更多的信息 
  Dim DynamicObj     As Object 
  Set DynamicObj = DynamicClassFactory.NewObj(Me.Text1) 
     '//从 DynamicClassFactory 中获得一个新类,该类 将继承 Text1 的所有属性 
  Debug.Print DynamicObj.Text 
     '//输出其 文本


DynamicObj.Properties.Add "NewTag", [A String], "增加一个 Tag 属性" 
  Debug.Print DynamicObj.NewTag 
     '//增加了一个属性 NewTag,并试图访问

  有的时候,我疑惑 TextBox 有Text 属性,而 DTpicker 有 Value 属性,同出而异名,异曲而同工,能不能也通过 Value 来访问 TextBox的Text属性呢? DynamicClassFactory 将支持你这么做. 

Dim Property       As DynamicClassFactory.Property 
  Set Property = DynamicObj.Properties("Text") 
  Property.Name = "Value" 
  Debug.Print DynamicObj.Value 
    '//这个时候,Value输出的是 Text1 的Text属性值

  当然了,当我么访问 DynamicObj.Text 的时候, 其实 DynamicClassFactory 返回的是一个 Property 对象,其有一个默认属性就是 Value 


  由此,我们实现更改属性称谓的实现也可以通过下面方式来进行 

DynamicObj.Text.Name = "Value" 
  Debug.Print DynamicObj.Value

  VB6可以说称不上支持重载,我有的时候疑惑,为什么不能在设置 Textbox 的 Enabled 属性为 False 的同时,其背景色同时换成灰色?即,我是否可以有一个机制,可以让一个类继承了 TextBox 的大多属性的同时 

   对其 Enabled 属性有一个扩充(重载)?答案是否定的,VB6不提供类似机制. 

   而我的 DynamicClassFactory 做到了这一点 

DynamicObj.Enabled = Flase 
   '//Text1 将 Disable,同时其背景色为灰

   有的时候 , 我们取得一个记录集(ADODB.Recordset), 在取值时候, 要逐个字段判断其值是否为NULL, 很烦恼.如果您有类似的烦恼, 请阅读下去! 

Dim Properties      As DynamicClassFactory.Properties 
  Dim SQL             As String 
  Dim Recordset       As ADODB.Recordset 

  SQL = "SELECT Name ,Age ,Sex From StudentsInfo" 
  Set Recordset = g_Cn.Execute(SQL) 
  Call DynamicObj.Bind(Recordset)

  这个时候 DynamicObj 将绑定到这个记录集,并按照 这个记录集的字段生成相应属性,并支持访问 


Set Properties = DynamicObj.Properties 
  For Each Property In Properties 
   Debug.Print Property.Name & ":" & Property.Value 
  Next 
    '//遍历属性成员 
  Debug.Print DynamicObj.Name 
     '//访问属性成员

  当然了,如果把 DynamicObj 的 BoundMode 设置成 BoundAutomatic(自动绑定)时,则当 Recordset 的 AbsolutePosition 发生变动时候, DynamicObj 各属性成员是动态刷新的,请看下面的例子 

Recordset.MoveFirst 
  DynamicObj.BoundMode = BoundAutomatic 

  Do While Not Recordset.EOF 
    Debug.Print DynamicObj.Name 
    Recordset.MoveNext 
  Loop 
    '//逐条输出学生的姓名

  当然了也可以: 

Recordset.MoveFirst 
  DynamicObj.BoundMode = BoundManual '//手动绑定 
  Do While Not Recordset.EOF 
    Call DynamicObj.Refresh '//手动刷新 
    Debug.Print DynamicObj.Name 
    Recordset.MoveNext 
  Loop 
    '//逐条输出学生的姓名

  DynamicClassFactory 不仅支持对象创建时的继承\运行中绑定 Recordset,还支持运行中继承,支持对普通类实例或是单层结构的 Type(UserDataType) 进行继承 

'//比如我们有如下的一个结构 
  Public Type LinkManType 
    Name           As String 
    Company        As String    '//公司 
    Telephone      As String    '//电话 
    MobilePhone    As String    '//移动电话 
    Position       As String    '//职务 
  End Type 

  '//下面演示结构继承 
  Dim LinkMan      As LinkManType 

  LinkMan.Company = "微软" 
  LinkMan.MobilePhone = "1361920XXXX" 
  LinkMan.Name = "周XX" 
  LinkMan.Position = "经理" 
  LinkMan.Telephone = "029-8888888" 
  Call DynamicObj.ExtendFrom(LinkMan) 
  Debug.Print DynamicObj.Name 
    '//输出 我的姓名

   如果我们有一个类,有上述 LinkManType 的结构,其实例名称为 cLinkMan,我们一样可以调用 ExtendFrom 来实现继承,至于手动对属性成员进行增\删\改,更是不在话下. 

   下次介绍函数重载及多态.敬请关注.



呵呵,大家可以不必看上面的介绍了:

[摘要]

   DynamicClassFactory ,一个支持在VB6里实现真正意义的继承,多态,重载的库,目前,DynamicClassFactory还在开发中,预计月底出测试版,届时提供网友下载使用.

[正文]

   DynamicClassFactory 将从根本上改变 VB6 开发者写作 类 的思维方式,支持您以纯面向对象的方式书写 类,比如:

Public clsMyClass        As DynamicClassFactory.Class
   Set clsMyClass = DynamicClassFactory.NewClass(ClassName:="clsMyClass", CodeContainer:= Me)

   这样,一个新类就诞生了,名称为 clsMyClass,代码写作的位置在 Me

   类该具备一些成员函数,下面增加成员函数,看看 DynamicClassFactory 如果是如何处理的

   Call clsMyClass.Members.Add(Name:="MyFunc", InvokeType:=[Invoke Func],DefaultValue=Empty , ProcAddress:=1)

   这样,类就添加了一个名称 为 MyFunc 的函数,函数处理代码 放在 Me 的倒数第 1 (ProcAddress) 个 方法中

   这样,clsMyClass 的实例在调用 MyFunc 的函数时,将自动映射到 Me 中的该代码块,如下例,

Private Sub MyFunc(Member As DynamicClassFactory.Member, InvokeType As  DynamicClassFactory.InvokeTypeEnum, Pms As DynamicClassFactory.Parameters, This As DynamicClassFactory.This, Result As DynamicClassFactory.Result)
     Result.Value = Pms(1).Value & Pms(2).Value & Pms(3).Value
       '//取得函数 返回值
   End Sub
   代码定义完毕,我们来尝试调用
   Dim MyInstance       As Object
   Set MyInstance = clsMyClass.NewInstance()
     '//取得 clsMyClass 的新实例
   Debug.Print MyInstance.MyFunc("A", "B", "C")
   我们 Debug 输出的结果将是 "ABC"

   有的时候,让们定义 某类成员处理函数的次序(ProcIndex),是很麻烦的,那有没有更好的处理办法呢?同样的例子,我们写在模块里,将更醒目,请注意 InitclsMyClass 中的第二行代码:

Public clsMyClass        As DynamicClassFactory.Class

   Public Sub InitclsMyClass()
     '//负责初始化 clsMyClass 类模板
     Set clsMyClass = DynamicClassFactory.NewClass(ClassName:="clsMyClass")
     Call clsMyClass.Members.Add(Name:="MyFunc", InvokeType:=[Invoke Func],DefaultValue=Empty , ProcAddress:=AddressOf MyFunc)
     '//添加以一个成员函数,其处理过程指向下面的 MyFunc 函数
   End Sub

   Public Sub MyFunc(Member As DynamicClassFactory.Member, InvokeType As DynamicClassFactory.InvokeTypeEnum, Pms As DynamicClassFactory.Parameters, This As DynamicClassFactory.This, Result As DynamicClassFactory.Result)
     Result.Value = Pms(1).Value & Pms(2).Value & Pms(3).Value
       '//取得函数 返回值
   End Sub

   当然了,当我们调用其实例的 MyFunc 函数时,将自动指向该Proc 进行处理,如:

Dim MyInstance       As Object
   Set MyInstance = clsMyClass.NewInstance()
     '//取得 clsMyClass 的新实例
   Debug.Print MyInstance.MyFunc("A", "B", "C")  
   当然了,我们也可以这样来调用该接口:
   Dim MyInstance       As Object
   Dim Func             as DynamicClassFactory.Func
   Set MyInstance = clsMyClass.NewInstance()
     '//取得 clsMyClass 的新实例
   Set Func = MyInstance.getFunc("MyFunc")
     '//获得该成员函数
   Debug.Print Func.Invoke("A", "B", "C")  
     '//输出

   这样的效果跟上述是一样的。

   待续,更多的精彩还在后头,下篇介绍,继承,多态,重载。


Demo 中的 NormalTest 演示 DynamicClassFactory 是如何凭空创建类,并实现类的继承,多态,函数重载等特性。

示例中用了三个类,最基础的类是 clsDog(狗),clsShepherdDog (牧羊犬),clsChinaShepherdDog(中国牧羊犬)

clsDog 有两个属性和一个函数方法

  EyeNumber        眼睛的数量

  LegNumber        腿的数量

  Yaff             吠叫     函数原型 Yaff(ToYaff  As String)

clsShepherdDog 继承自clsDog ,另外还具备自己的特性:

  Shepherd         放养,函数原型为 Shepherd(intCount As Integer),代表领着几只羊出去放

  另外,有一点 clsShepherdDog 很厉害,他的 Yaff 跟普通的狗不一样,普通的狗所有的东东都可以,而 clsShepherdDog 只会说 Yes Sir 和 No Sir

老大当然是我们的 中国牧羊犬(clsChinaShepherdDog) 了,他除了继承 普通牧羊犬 的所有特性外,还有一点就是他很聪明,可以知道放羊结束后数羊(Count)然后向主人汇报结果(Report)

  Count           见到羊就数数量,并作加法运算,累计数量, 函数原型 Count(intCount As Integer)

  Report          汇报数量


下面的例子将演示一只中国牧羊犬放羊,数羊并回来汇报的过程

提供的机制非常简单,但是您能用这个机制写出什么类,那是我所没有办法想象的,因为这已经具备了OOP的最基本特质。

这个版本由于是初级版本,速度还是一个问题,我会在下面的版本中注意这些特性的。

下个版本中,我将增加构造函数的部分。

最后,这个东东纯粹是为了弥补 Vb6 的一些缺憾,如果要想更爽地 OOP 建议用 DotNet 或是 Java,还有,就是不建议大面积使用,因为速度可能是一个无法突破的瓶颈。

谢谢关注!


                                             Howtell Soft





【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
M9aMEIE19lAW