Groovy探索之MOP 十五 方法名的动态性(1)

Groovy探索之MOP 十五 方法名的动态性(1),第1张

概述         Groovy探索之MOP 十五  方法名动态性(1)       到目前为止,我们的《Groovy探索之MOP》系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法。即我们添加一个方法名为A的方法,然后才能使用这个方法A。

         Groovy探索之MOP 十五  方法名的动态性(1

 

 

 

到目前为止,我们的《Groovy探索之MOP》系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法。即我们添加一个方法名为A的方法,然后才能使用这个方法A

然而,方法名的动态性,其实是我们早已接触过的事情,比如在《Groovy探索之invokeMethod方法》里,我们就可以创建形如“sortByXxxxx()”这样漂亮的方法。当然了,在那篇文字里,我们是通过“invokeMethod”方法来实现的。

我们都知道,使用ExpandoMetaClass在运行期内给一个对象或类添加一个方法要比hook方法简单得多,所以,我们在实际的编码过程中,更多时候会用到ExpandoMetaClass来实现。那么,我们使用ExpandoMetaClass是否也可以实现上面hook方法所实现了的方法名的动态性呢?

我们知道,使用ExpandoMetaClass在运行期内添加一个方法(不管是给对象还是给类),形式都是像下面的样子:

 

类名.MetaClass.方法名 = 方法体

 

同时,上面的公式还可以写成如下的样子:

 

 

类名.MetaClass. "方法名" = 方法体

 

这下我们明白了,既然方法名可以用双引号括起来,那么,如果双引号里面是一个Gstring对象的话,这样,我们就可以给方法赋予一个可变的数据了。从而达到了我们使用ExpandoMetaClass实现方法名的动态性的目的了。

 

废话少说,我们还是先来看一个例子吧!

 

现在,我们有一个T类,如下:

 

class T

{

   

}

 

 

我们就可以这样对T类添加方法:

 

      String functionname = "a";

     

      T.MetaClass."$functionname" = {

             println "invoke $functionname"

      }

     

      def t = new T()

     

      t.a()

   

 

我们在添加方法的时候,使用了一个Gstring对象来代替了写死的字符串,这样就实现了方法名的动态性。运行结果为:

 

invoke a

 

当然了,你可能会觉得上面的方法名的动态性还不够清晰,那么,我们可以实现如下的一个静态方法,来达到我们方法名动态性的目的:

 

    def static add(functionname)

    {

       T.MetaClass."$functionname" = {

                println "invoke $functionname"

         }

    }

   

 

这样,我们就可以如下来使用它了:

 

      add('b')

     

      def t1 = new T()

     

      t1.b()

     

     

      add('c')

     

      def t2 = new T()

     

      t2.c()

   

 

运行结果为:

invoke b

invoke c

 

上面的例子只是小儿科,我们使用ExpandoMetaClass实现的方法名的动态性同样可以使用于《Groovy探索之invokeMethod方法》中的那个有名的例子。关于那个例子的来历,大家可以在原文中看到,这里就不再重述。

在那篇文字中,Student类是这样的:

class Student {

   

    String no;

    String name;

    float chinscore;

    float mathscore;

    float englscore;

    float physscore;

    float chemscore;

    float totalscore;

 

}

 

 

同样,我们的那个排序工具类还是保留,只是不再实现它的排序方法了,如下:

 

class SortHelper

{

 

    def List

   

    public SortHelper(List)

    {

       this.List = List

    }

 

}

 

 

当然,我们的排序方法是要留给ExpandoMetaClass来实现的,下面就是:

 

      ['chinscore','mathscore','englscore','physscore','chemscore','totalscore'].each{

         name ->

           def name1 = name[0].toupperCase()+name[1..-1]

           SortHelper.MetaClass."sortBy${name1}" = {

               -> 

                  def comparator = {

                         node1,node2 ->

                         return node1."${name}".compareto(node2."${name}")

                  } as Comparator

                 

                  Collections.sort(delegate.List,comparator)

           }

      }

 

 

 

我们的想法就是,把要实现的方法的方法名(或部分)组成一个数组,然后依次遍历,交给ExpandoMetaClass来添加方法。

上面的代码都很简单,在这里我们就不再多说了。

最后,我们来写代码测试上面的添加方法了。如下:

总结

以上是内存溢出为你收集整理的Groovy探索之MOP 十五 方法名的动态性(1)全部内容,希望文章能够帮你解决Groovy探索之MOP 十五 方法名的动态性(1)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1271026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存