[中级] Func() 和 ObjBindMethod() 的关系

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,先把是狗还是羊提供一下。

image

;示例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元编程初步:对象协议和__Get() v2

[中级] AHK元编程实战:用__Call()魔改默认基对象 v2

End

心如止水是Java/AHK持续学习者,欢迎您来和我探讨Java/AHK问题 ^_^

GitHub

欢迎您来访问我的GitHub,在这里您可以看到我的代码分享,关注我的最新动态。

欢迎给 新生的 BeanLib 投稿,每一位贡献者的名字都将被铭记。

更多文章:

问题解答:

[问题解答] 示例不能运行吗? - 关于AHK程序设计系列文章示例问题的解释

版权声明:

该文章版权系“心如止水”所有,欢迎分享、转发,但如需转载,请联系QQ:3404624865,得到许可并标明出处和原链接后方可转载。未经授权,禁止转载。版权所有 ©心如止水 保留一切权利。

文章版本:

v1

AHK版本:1.1.30.00

心如止水

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值