AB013-[中级] Func() 和 ObjBindMethod() 的关系
上一篇文章发出来之后,@zhanglei1371 问我 " Func 和 ObjBindMethod 的关系"。
其实"只要是方法就用 ObjBindMethod ,只要是函数就用 Func",大多数时候都是没问题的。
但是深究下去,他们之间是有区别的。
这是个好问题,顺带我介绍一下 Class 的内容。
Class 和 Object
这个地方学过"面向对象"的,可以跳过,这是给没学过的说的。
情景
面向过程
现在假设你要做一款儿童游戏,你需要模拟出很多小动物,比如狗/羊等等。你一开始可能这么搞。
DogSound:="汪汪~~"
DogName:="狗"
DogCalling(){
global
MsgBox,% DogName ":" DogSound
return
}
DogFuncObj:=Func("DogCalling")
%DogFuncObj%()
是,今天是没问题了,但是明天老板让你做一只羊,后天老板让你做一只猴子,一只兔子,一只考拉。
所以你就复制/粘贴/复制/粘贴,这么一直不停的堆积代码的办法就叫做"面向过程"。
面向对象
由于你做的动物非常多,"动物"这种东西又很有相似性,还有一个办法就是,你先做一个"动物"模板,之后每增加一个新动物,你就往里面填东西就是了。这个办法更方便,更符合人类的认知规律。
这个模板就叫做 Class
,翻译过来就是"类",用现代汉语来说就是"种类"。现在我们定义一个Class
。
;示例1
Class Animal{
;Field
Sound:="UnKnowSound"
Name:="UnKnowName"
__New(aName,aSound){
this.Name:=aName
this.Sound:=aSound
return this
}
Calling(){
MsgBox,% this.Name ":" this.Sound
return
}
}
你可以根据这个模板,批量的生成大量的动物,节省你很多的时间。
但是你要明白的是,动物
本身是一个抽象的概念,他只是一个"种类",并不是一个实体,而你要生成的狗
就是一个实体,实体
的英文就是Object
。这个Object
常被翻译为"对象",这种编程的方法也叫做"面向对象的编程吧"。
下面我们来生成一只狗和一只羊,他们都属于Object
。
TheDog:=new Animal("Dog","汪汪~")
TheSheep:=new Animal("Sheep","咩咩~")
现在我们让他们都叫叫,听听声。
TheDog.Calling()
TheSheep.Calling()
狗叫和羊叫
Func 和 ObjBindMethod 的关系
问题在于"面向对象"
搞清楚这一点了之后,"Func 和 ObjBindMethod 的关系"其实就很容易理解了。
比如,你想获取一个"狗叫"的函数对象,你可能要把它用在HotKey
命令中。(当然,这种没参数的方法可能简单些,这里就当有参数。)
如果你是面向过程,也就是定义的函数
,那么你需要这么做。
;示例2
DogSound:="汪汪~~"
DogName:="狗"
DogCalling(){
global
MsgBox,% DogName ":" DogSound
return
}
DogFuncObj:=Func("DogCalling")
%DogFuncObj%()
但是,现在你用的是"面向对象",那么你就不能用这种方法。
DogFuncObj:=Func("Calling")
%DogFuncObj%()
因为,你只提供Calling
这个方法名,程序不知道该调用狗
的还是羊
的,程序默认在函数
中搜索,又找不到一个叫做Calling
的函数,那么就会返回false
。
那么就用ObjBindMethod
,先把是狗还是羊提供一下。
;示例3
DogFuncObj2:=ObjBindMethod(TheDog,"Calling"),%DogFuncObj2%()
那么能不能用Func()+Bind() 完全替代 ObjBindMethod()?
大多情况下可以相互代替
大多数情况是可以的,但也有例外。首先我们看一下示例1,你会发现一个this
关键字。
这个this
是什么意思呢?因为在你建立Class
的时候,你并不知道将来是狗
还是羊
,那么你就用this
来泛指一切动物对象
。
;示例4
Calling(){
MsgBox,% this.Name ":" this.Sound
return
}
再看一下这个方法,方法的域是独立的,方法中本没有一个叫做this
的东西,那么this
从哪里来?
答案是,this
从参数中来,其实这个方法的本来面貌应该是。只是为了可读性,省略了罢了。
;示例5
Calling(this){
MsgBox,% this.Name ":" this.Sound
return
}
所以,Func()+Bind() 可以替代 ObjBindMethod(),方法如下。
;示例6
DogFuncObj3:=TheDog.Calling.Bind(TheDog),%DogFuncObj3%()
示例3和示例6是完全等价的。
特殊情况下不能代替
之所以我们能够这么用,是因为TheDog.Calling
这个东西是我们自己搞出来的,我们对这个FuncObj
本身具有访问权限。但是,对于系统自带的Obj,比如FileObj
,我们是没有这个权限的,在这种情况下,我们就只能用ObjBindMethod
。
;示例7
file := FileOpen("D:test.txt", "r")
getLine := ObjBindMethod(file, "ReadLine")
getLine2 := file.ReadLine.Fucn(file)
MsgBox % %getLine%()
MsgBox % %getLine2%()
第一次 %getLine%()
可以读出文字,第二次%getLine2%()
就生没辙,因为file.ReadLine
你没有权限拿到。
这个系列的其他文章
看这里
[中级] AHK元编程实战:用__Call()魔改默认基对象 v2
End
心如止水是Java/AHK持续学习者,欢迎您来和我探讨Java/AHK问题 _
GitHub
欢迎您来访问我的GitHub,在这里您可以看到我的代码分享,关注我的最新动态。
欢迎给 新生的 BeanLib 投稿,每一位贡献者的名字都将被铭记。
更多文章:
- [专栏] AHK程序设计 - 简书(优先持续更新)
- [基础] [GIF动图] 绕过中文输入法发送文本的3种方法
- [基础] AHK函数对象系列-绑定函数对象v3
- [基础] AHK函数对象系列-绑定方法对象
- [基础] 在AHK中实现函数重载的效果
- [基础] AHK函数对象系列-对象属性与数据域保护v2
问题解答:
[问题解答] 示例不能运行吗? - 关于AHK程序设计系列文章示例问题的解释
版权声明:
该文章版权系“心如止水”所有,欢迎分享、转发,但如需转载,请联系QQ:3404624865,得到许可并标明出处和原链接后方可转载。未经授权,禁止转载。版权所有 ©心如止水 保留一切权利。
文章版本:
v1
网友评论