注册 登录
编程论坛 VFP论坛

分享: 如何为自己对象设置一个只读属性

sam_jiang 发布于 2024-04-05 22:04, 453 次点击
我们在写程序的时候往往会希望某个属性值不能被用户随意更改,但可以读取。
很可惜FoxPro不支持设计一个只读属性,要么保护,要么隐藏,可是一旦保护或隐藏了,就无法直接访问,只能通过内建的方法去访问这个值,挺麻烦的。
于是,我利用属性的assign方法设计了一个方法去模仿设立一个只读属性,完美解决这个问题。
首先,设置一个revisor属性,默认为空;
其次,通过一个方法来修改这个属性的值,只有这个方法才可以修改此属性的值;
最后,给需要设置为只读的属性分配一个assign方法,检查revisor的值,如果revisor是我们设定的那个方法,则修改它的值,否则拒绝;

演示代码实现如下:
程序代码:

clea
SET DATE TO long
otest=CREATEOBJECT('employee')
?[原来的hiredate:]
??otest.hiredate
otest.hiredate={^2022-12-01}
?[通过给otest.hiredate赋值修改日期为2022-12-01,但没有成功:]
??otest.hiredate
otest.sethiredate(DATE())
?[通过方法sethiredate()程序成功修改:]
??otest.hiredate

DEFINE CLASS employee AS CUSTOM
    *!*    HIDDEN HireDate
    *!*    PROTECTED HireDate
    First_Name = "Jiang"
    Last_Name = "Sam"
    Address = ""
    HireDate = {^2017-06-05}
    revisor=[] &&用来判断修改者

PROCEDURE GetHireDate
  RETURN This.HireDate
ENDPROC

PROCEDURE hiredate_assign
PARAMETERS m.vnewval
m.voldval=this.hiredate

if strextract(this.revisor,[.],[])==UPPER([sethiredate])
*!*    检查revisor修改者是不是我们制定的方法   
    this.hiredate=m.vnewval
    this.revisor=[] &&恢复不可修改状态
ELSE
    this.hiredate=m.voldval
ENDIF

   
PROCEDURE sethiredate
    PARAMETERS hiredate
    this.revisor=PROGRAM() &&传递方法名给属性revisor
    this.hiredate=hiredate
   
ENDDEFINE


win7+foxpro9.0下 编译通过。
10 回复
#2
sam_jiang2024-04-05 22:35
hiredate_assign 有个bug,如果在一个多层次对象中,判断reivsor会出错,要修改一下。

PROCEDURE hiredate_assign
PARAMETERS m.vnewval
m.voldval=this.hiredate
n=occu([.],this.revisor)
if strextract(this.revisor,[.],[],n)==UPPER([sethiredate])

*!*    检查revisor修改者是不是我们制定的方法   
    this.hiredate=m.vnewval
    this.revisor=[] &&恢复不可修改状态
ELSE
    this.hiredate=m.voldval
ENDIF
#3
schtg2024-04-06 05:42
谢谢!
#4
sych2024-04-06 09:47
方法清新脱俗,新颖奇特,实用精炼,非常感谢分享
#5
easyppt2024-04-06 10:10
谢谢分享,好注意,延伸一下还可以实现隐藏功能,即不可以读。

另外 ,作为条件属性:revisor,为什么要考虑层次关系,不能直接设置结果吗,比如:.T.可以改,.F.不可以改,这样不知道妥不妥。

#6
sam_jiang2024-04-06 11:36
回复 5楼 easyppt
最初也是简单设置个逻辑值来作开关阀,但是容易被用户更改这个开关,导致属性被修改,设置一个revisor之后,用户就不能更改这个值了,就算更改了,也不知触发的值是多少,除非他知道源代码。。。
#7
cssnet2024-04-06 11:41
以前看C#、Java教程时,印象中这么干:

假设在类中,有一个private变量(私有字段):
_hiredate
相应地,又另有一个public(公有属性):
Hiredate

其他任何类或对象,是无法访问类的私有变量_hiredate的,而只能访问类的公有属性Hiredate。

只需编写好Hiredate属性的get/set方法:

publce int Hiredate
{
get{retrun _hiredate;}
set{_hiredate = value;}
}
若想要属性Hiredate“只读”,set方法清空即可。
至于属性Hiredate的赋值,在构造函数里。

理论上,VFP采用的也是类似方法吧?
Access 和 Assign 方法,对应的正是get/set方法。
若没有构造函数,那就给类加一个private变量_startup,初始值为.t.,初始化完成后为.f.;
在Assign 方法中,加个判断:
if ! _startup
     return
endif

估计会好使。

#8
laowan0012024-04-06 17:23
楼主的用户可以操作属性?如果给用户提供EXE是不是就不存在这些问题了
#9
sam_jiang2024-04-06 20:15
回复 8楼 laowan001
封装类给别人使用,呵呵
#10
shizi02024-04-07 23:24
思路很容易想到,但一般人都没这个心,或不愿去下这个力气。细节不容易,既封装又适配性强,那更要N多实践验证和提升。感谢分享
#11
laowan0012024-04-08 08:00
以下是引用sam_jiang在2024-4-6 20:15:33的发言:

封装类给别人使用,呵呵

原来酱紫啊
1