Groovy探索之运算符的重载 二
?
??????????Groovy探索之运算符的重载 二
?
?
前一篇详细的说了说算术运算符和关系运算符的重载,这篇要说说赋值运算符和取值运算符,即“.”运算符的重载。 还是以前一篇的Yuan类来作为例子。 class Yuan { ??? def num
?
??? def toString() ??? { ?????? this.num ??? } }
?
?
有了上面的类的定义,我们就可以如下使用这个类: ??? ? def y = new Yuan()
?
?????? y.num = 109 ?????? ?????? ??? println y.toString()
?
其中,“y.num = 109”就是一个赋值语句,关键的运算符就是“.”;当然,我们还可以用该运算符进行取值运算,如下:
?
?????? println y.num ??? 我们今天要说的就是对“.”运算符的重载。当然,只要我们稍微一想,就可以知道,该运算符应该和“set”和“get”方法有关。不错,的确如此。 下面,我们来看看如何重载“.”运算符。 class Yuan { ??? def num ??? ??? def getOwner() ??? { ?????? print 'tom' ??? } ??? ??? def toString() ??? { ?????? this.num ??? } }
?
要重载取值运算,当然只要“get”方法就行了,注意看代码中的“getOwner()”方法,实现了它,我们就可以写出“y.owner”这样的代码来。 下面来看我们的测试代码: ??? ? ??? ? def y = new Yuan(num:100) ??? ? ??? ? y.owner ? println " has ${y.toString()} yuan."
?
运行结果为: tom has 100 yuan.
?
当然,重载赋值运算就和“set”方法相关了,如下: class Yuan { ??? def num ??? ??? def setOwner(name) ??? { ?????? println name ??? } ??? ??? def toString() ??? { ?????? this.num ??? } }
?
测试代码如下: ??? ? def y = new Yuan(num:100) ??? ? ? y.owner = 'mike'
?
可以看到,“.”运算符的重载跟其他运算符的重载也都一样,没有什么特别的地方。但为什么要把它拿出来单独成一篇呢?这是因为它跟DSL有很大关系,是Groovy语言实现DSL的一种方式。 下面就来说一说如何使用“.”运算符来实现DSL的。 一直以来,我们都希望计算机能够识别我们人类的自然语言,如它能够帮我们计算这样的题目: 12元+39毛+123分 当然,现在的计算机还不能做到这样的场景。但是,现在有了DSL,我们能做到这样的场景: 12.yuan+39.jiao+123.fen 这样,就相当的接近我们的自然语言了。那么,Groovy语言是怎么实现上面的场景的呢? 一看到“12.yuan”这样的表达式,我们就可以想到,这不就是一个取值运算吗?我们可以重载“.”运算符。 不错,Groovy语言正是通过重载“.”运算符帮我们实现上面的场景的。既然要重载“.”运算符,那么“12”又是一个什么对象呢?在Groovy语言中一切都是对象,“12”是一个Integer对象。 对啦,我们只需要在Integer类里实现getYuan()方法,就可以重载取值运算符。但Integer类是一个已经存在的类,我们不能直接修改它。 那么我们怎么给Integer类添加getYuan()方法呢?是的,通过metaClass,即元对象。 下面是实现上面的场景的代码:
?
??? ? def mc = new ExpandoMetaClass(Integer.class,true) ??? ?? ??? ? mc.getYuan << ??? ? { ?????? ? -> ?????? ? ? delegate as float ??? ? } ??? ? ??? ? mc.getJiao << ??? ? { ?????? ? -> ?????? ? ? def j = delegate as float ?????? ? ? j/10 ??? ? } ??? ? ??? ? mc.getFen << ??? ? { ?????? ? -> ?????? ? ? def f = delegate as float ?????? ? ? f/100 ??? ? } ??? ? ? mc.initialize()
?
?
首先取得Integer类的元对象:“def mc = new ExpandoMetaClass(Integer.class,true)”。 然后,再添加各个“get”方法,因为我们只需要实现取值运算,因此,只需要实现“get”方法就可以了。 最后实例化这个元对象,即“mc.initialize()”
?
现在,我们来测试这段代码:
?
??? ? println 12.yuan+45.jiao+33.fen ??? ? ???
?
结果为: 16.83
?
?
运算符的重载是Groovy语言实现DSL的一个很重要的方面,因此,我们拿出两个章节才把它说完,希望我们在今后的编码实践中经常的使用到它。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |