Groovy探索之invokeMethod方法
发布时间:2020-12-14 17:00:16 所属栏目:大数据 来源:网络整理
导读:???????????????????????? Groovy探索之 invokeMethod 方法 ? 我们知道,在Java语言中,所有的Java类都继承了Object对象。通过Object对象,所有的Java类都隐藏的实现了“equals”等方法。同样,在Groovy语言中,所有的Groovy类都隐藏的实现了GroovyObject接
????????????????????????
Groovy探索之invokeMethod方法
?
我们知道,在Java语言中,所有的Java类都继承了Object对象。通过Object对象,所有的Java类都隐藏的实现了“equals”等方法。同样,在Groovy语言中,所有的Groovy类都隐藏的实现了GroovyObject接口,这样,我们的Groovy类就隐藏的实现了很多的方法,如“isCase”等。
这篇文字要谈谈的就是GroovyObject接口的“
invokeMethod”方法,这个方法对于我们Groovy语言的动态性编程很有帮助,可以帮助我们实现一些很有时代性的功能,比如DSL。本文就是要谈谈“
invokeMethod”方法的基础,通过这个基础,我们才可以通向DSL编程。
首先,我们来看看“
invokeMethod”方法在一个Groovy类中的作用,先来看一个例子:
class
InvokeMethodTestor {
???
???
def
test
()
??? {
??????
println
'hello,function name is test'
??? }
???
???
def
invokeMethod(String name,Object args)
??? {
??????
println
"the other function,name is ${name}"
??? }
?
}
?
这是一个很简单的
Groovy
类,我们有一个
test
方法,用来向控制台打印一句话;然后我们实现了
invokeMethod
方法,并且把参数“
name
”打印在控制台。
在讲述“
invokeMethod”方法的作用之前,我们先来测试一下上面的类。
def
testor =
new
InvokeMethodTestor()
??? ?
??? ?testor.
test
()
??? ?
??? ?testor.hello()
??? ?
?testor.doSomething()
?
我们先来看看测试结果:
hello,function name is test
the other function,name is hello
the other function,name is doSomething
?
通过测试结果,我们可以看出,语句“
testor.
test
()
”调用了“
InvokeMethodTestor
”类的“
test
”方法,而语句“
testor.hello()
”和“
testor.doSomething()
”却都调用了“
InvokeMethodTestor
”类的“
invokeMethod
”方法。
这就告诉我们,对于一个实现了“
invokeMethod
”方法的
Groovy
类的对象,可以执行任意的方法,如果该方法已经在该类中实现,就调用该方法,如“
testor.
test
()
”就调用“
InvokeMethodTestor
”类的“
test
”方法;如果该方法没有在该类中实现,如“
testor.hello()
”和“
testor.doSomething()
”,就调用该类的“
invokeMethod
”方法。
这样说来,“
invokeMethod
”方法其实蛮简单的,一点都不神秘和麻烦。但是它的作用却一点都不能小觑,它给我们的
Groovy
语言编程带来了很大的动态性。
下面试着举一个小小的例子说明。
比如,我们有一个
Student
类,里面放的是学生的成绩,如“语文”、“数学”、“英语”等等,如下:
class
Student {
???
??? String no;
??? String name;
???
float
chinScore;
???
float
mathScore;
???
float
englScore;
???
float
physScore;
???
float
chemScore;
???
float
totalScore;
?
}
?
同时,我们有一些学生(已经记录的各科成绩)在一个
List
对象里,如下:
List scores = [
new
Student(no:
'123'
,name:
'Tom'
,chinScore:
90
,mathScore:
99
,englScore:
60
,physScore:
88
,chemScore:
96
)]
??? ?scores<<
new
Student(no:
'124'
,name:
'Mike'
,chinScore:
88
,mathScore:
90
,englScore:
90
,physScore:
98
,chemScore:
87
)
?scores<<
new
Student(no:
'125'
,name:
'Alice'
,chinScore:
100
,mathScore:
55
,englScore:
98
,physScore:
67
,chemScore:
56
)
?
这些学生在
List
对象里是以学号排序的,我们来看看:
??? ?scores.
each
{
?????? ?
println
it.name+
' : '
+it.no
?}
?
结果为:
Tom : 123
Mike : 124
Alice : 125
?
可以看到的确如此。
下面,我们的语文老师希望以语文成绩排序,而数学老婆希望以数学成绩排序,英语老师则希望以英语成绩排序,
……
,班主任则希望以总分排序。
看到这里,你可以会说,我做一个方法来实现所有老师的愿望,这个方法有两个参数,一个是
List
对象,一个是
type
,
type
参数用来表示语文老师要的语文,数学老师要的数学等等。
这个方法当然是不错的,但不是最酷的。最酷的方法是语文老师调用
sortByChinScore
()方法,而数学老师调用
sortByMathScore
()方法,英语老师调用
sortByEnglScore
()方法,等等。
且慢!这不是要我写六七个方法来实现所有老师的要求?这未免有点无聊吧?像这样的代码写起来也枯燥乏味呀。
当然不用写六七个方法,答案就是“
invokeMethod
”方法。我们来看看是如何实现这样一个想法的:
import
java.util.Collections
import
java.util.Comparator
?
class
SortHelper{
???
???
def
list
???
???
public
SortHelper(list)
??? {
??????
this
.list = list
??? }
???
//
所有的以
sort
开头的方法都来调用“
invokeMethod
”,当然,其他方法也有可能
//
来调用它,但我不做处理。
???
def
invokeMethod(String name,Object args)
??? {
??????
//
首先判断方法名是否以“
sortBy
”开头,是则处理,否则不处理。
??????
if
(name.indexOf(
'sortBy'
)==
0
)
?????? {
??????????
??????????
//
取得属性名,如“
ChinScore
”
?????????? name = name[
6
..name.length()-
1
]
??????????
??????????
//
把第一个字母由大写变小写,就取得了属性名
?????????? name = name[
0
].toLowerCase()+name[
1
..name.length()-
1
]
??????????
??????????
//
实现
Comparator
接口,大家可以参考
jdk
文档。
??????????
def
comparator = {
????????????????? node1,node2 ->
?????????????????
return
node1.
"${name}"
.
compareTo
(node2.
"${name}"
)
?????????? }
as
Comparator
??????????
??????????
//
排序
?????????? Collections.
sort
(
this
.list,comparator)
??????????
?????? }
??? }
?
}
?
真的很简单。下面我们来测试一些这个类:
??? ?
def
sorter =
new
SortHelper(scores)
??? ?sorter.sortByChinScore()
??? ?
??? ?scores.
each
{
?????? ?
println
it.name
?}
?
结果为:
Mike
Tom
Alice
?
从语文成绩来看,
Mike 88
,
Tom 90
,
Alice 100
。排序是正确的。下面我们以数学成绩排序:
?
??? ?sorter.sortByMathScore()
??? ?
??? ?scores.
each
{
?????? ?
println
it.name
?}
?
结果为:
?
Alice
Mike
Tom
?
从数学成绩来看,
Alice 55
,
Mike 90
,
Tom 99
,排序也没有问题。大家可以再测几个看看。
像这样的功能的确够酷,我们今后在
Groovy/Grails
平台会经常遇到;同时,这样一个思想也可以发展成
DSL
的一种实现。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |