VFP如何做一个超类,如此万物皆对象

2023-08-21 18:06:07 浏览数 (2)

VFP 本身的 面向对象(OOP) 概念本质上是“不完整”的。一个典型的无法解决的问题就是,VFP 中没有“超类”的概念。

所谓“超类”,也就是说,其他所有的类都是从它继承而来。.NET 中对 Object 类的描述如下:支持 .NET 类层次结构中的所有类,并为派生类提供低级别服务。 这是所有 .NET 类的最终基类;它是类型层次结构的根。换句话说,整个 .NET 平台上所有的类,都是从 Object 类继承而来。

如果 VFP 中存在“超类”会是怎样一个世界?

事实上是没有。但是不妨碍我们在一定程度上模拟一下“超类”!

在日常编程过程中,UI 是重要的表现方式。在 VFP 中,有各种可视化控件,也存在基于它们所创建的所谓自定义类。有时,我们会面对这样的困境:如果 Container 类和 Text 类是从同一个超类继承而来,那么,这个设计会简化不少啊!

然后,你很苦逼的在 Container 类和 Text 类中,重复定义相同的自定义方法和自定义属性,如果足够幸运,代码仅仅只需写一次,然后复制到另一个类的同名方法中......若干天/年之后,当你需要修改它们的时候,如果你忘记了,结果可能是冥思苦想也想不出问题出在哪里......其实仅仅是你修改了一个方法,忘记了另一个同名方法。

现在是结束这种苦逼心情的时候了!我们在 VFP 中模拟一个所谓的“超类”!

(超类一个特性是可以被继承表现为不同的可视化或非可视化的类。这里,仅仅是针对可视化类进行讨论)

首先,我们定义一个自己的超类:myObject

代码语言:javascript复制
Define Class myObject As Custom
  *!* 超类具有一个“固定的”自定义属性,用于存储“父对象”的对象引用
  oParent = .Null.

  Procedure Init
    Lparameters toObject

    This.oParent = m.toObject
  Endproc

  Procedure Destroy
    Try
      This.oParent = .Null.
    Catch
    Endtry
  Endproc

  *!* 获取属性值
  Procedure GetValue
    Lparameters tcPropertyName
    
    Return This.&tcPropertyName.
  EndProc
  
  *!* 设置属性值
  Procedure SetValue
    Lparameters tcPropertyName, tvValue
    
    This.&tcPropertyName. = m.tvValue
  EndProc
Enddefine

从这个 myObject 继承出第一个子类:myChild

代码语言:javascript复制
Define Class myChild As myObject
  *!* 假设此时新增了 cusC 和 cusD 两个自定义属性
  *!*
  cusC = .T.
  cusD = Date()

  *!* 子类具有一个名为 test 的自定义方法,它可以被 Container 类和 Text 类所共用
  Procedure test
    *!* 这里是实际的代码或者仅仅是一个虚方法
  EndProc
Enddefine

在我们的 Container 类和 Text 类中,同时增加一个自定义属性:oProxy,并在各自的 Init 事件中添加以下代码:

This.oProxy = CreateObject([对象名], myChild)

这样,Container 类和Text 类,就好像具有同一个超类 myObject :)

如果我们需要设置属性值,仅需这样:

代码语言:javascript复制
This.oProxy.SetValue([cusC], .F.)                            && This.oProxy.cusC = .F.
This.oProxy.SetValue([cusD], Date()   1)              && This.oProxy.cusD = Date()   1

获取某个属性值仅需这样:

代码语言:javascript复制
This.oProxy.GetValue([cusC])                               && This.oProxy.cusC
This.oProxy.GetValue([cusD])                               && This.oProxy.cusD

执行方法:

This.oProxy.Test()

OK!到此为止,我们在 VFP 中,也似乎拥有了“超类”!

0 人点赞