Groovy探索之方法调用的动态性

                      Groovy探索之方法调用的动态性

 

 

在我以前的文字中,我一再强调,Groovy语言的方法也和Java语言的方法一样,是要依赖于类和对象的,因此,方法不能被单独作为对象传递和循环。同时,在《Groovy探索之闭包 八》中,我们提出来一个能让方法进行传递和循环的一个替代方案,这就是使用闭包来代替方法。

其实,Groovy语言的方法虽然也依赖于类和对象,但却并不妨碍Groovy语言的方法调用的动态性,也使得Groovy语言在方法的调用上与Java语言的不同特点,这就是我们这篇文字所要谈到的内容。

当然,Groovy语言的方法调用的动态性要归功于Gstring的动态性。下面试着举出一些简单的例子来说明。

比如说,我们有一只可爱的小狗,它有一些可爱的动作,现模拟如下:

 

 

 

class Dog

{

    def bark() {

       println 'woof!'

    }

   

    def sit() {

       println 'sitting!'

    }

   

    def jump() {

       println 'boing!'

    }

   

}

 

现在,我们可以让它依次做上述的三个动作了:

 

     

      def dog = new Dog()

     

      def acts = ['sit','jump','bark']

     

      acts.each{

         dog."${it}"()

      }

 

运行的结果为:

sitting!

boing!

woof!

 

你会说啊,这基本上可以说是实现了命令模式了,不知道它的扩展性怎么样?我们现在可以试着让小狗多会一些动作了:

 

 

class Dog1 extends Dog

{

    def run()

    {

       println 'running...'

    }

}

 

看看小狗会了这个动作没有?

 

 

       def dog = new Dog1()

      

       def actions = ['sit','jump','bark','run']

      

       actions.each{

           dog."${it}"()

       }

 

运行结果为:

sitting!

boing!

woof!

running...

 

不错啊,也有很好的扩展性。方法的动态性还有一个重要的内容就是要传递方法,这在Groovy语言中也可以通过传递对象来实现。请看下面的例子。

还记得我们在《Groovy探索之闭包 八》中对一盏灯的控制吗?我们有一个开灯的动作,如下:

 

class LightOn

{

    def doing()

    {

       println 'Ligth turning on...'

    }

}

 

 

当然,我们也有一个关灯的动作:

 

class LightOff

{

    def doing()

    {

       println 'Ligth turning off...'

    }

}

 

我们有一个开关,要控制这盏灯,它本身不能控制灯,而是由传入的动作决定的,如下:

 

 

class Switch

{

    def control(action)

    {

       action."doing"()

    }

}

 

 

下面,我们就可以把开关灯的一些动作传递给Switch类的方法了:

 

     

      def sh = new Switch()

     

      sh.control(new LightOn())

 

运行结果为:

Ligth turning on...

 

这个实现就跟Java语言对于命令模式的实现很相似了,只是少了接口。原因是我们在Groovy语言中只要约定所有类的方法名都一样,我们就可以在客户端里使用“对象.方法名()”的形式调用该方法。而不同的动作则是通过对象的不同来区分的,这点跟Java语言很相似。只是在Groovy语言中有了“对象.方法名()”形式的方法调用,就可以不使用接口而调用方法了。

 

通过这样一种方法调用的动态性,我们就可以实现Java语言中的很多中模式了,比如命令模式和策略模式等等。

 

再次总结一下上面的Groovy语言的方法调用的动态性的实现,在Groovy语言中,我们可以使用两种方式变相实现方法调用的动态性:一是利用Gstring的动态性,固定类和对象,将方法名作为对象进行循环和传递,再利用“对象.方法名()”来实现方法的动态调用;二是固定方法名,以不同的类和对象来代表不同的动作,然后循环和传递对象,利用“对象.方法名()”来实现方法的动态调用。

两者都是最终要通过“对象.方法名()”来实现方法的动态调用的。那么有人要问了,如果我们的方法有参数的话,该怎么使用呢?

下面试着举出一个例子来说明这个问题,同时作为本篇的结束。

 

class Tools

{

    def max(int i1,int i2)

    {

       Math.max(i1,i2)

    }

}

 

下面,我们来使用这个Tools类:

     

      def arg = [1,2]

     

      def tools = new Tools()

     

      println tools."max"(*arg)

 

 

可以看到,我们将参数按照先后顺序放在一个List对象里,然后再将该对象传给如下的这种形式:

对象.方法名(*List对象)

 

上面代码的运行结果为:

2

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值