以 groovy 的方式实现接口

用闭包来实现接口

    如果接口只有一个方法,可以通过闭包,用下面的方式来实现:

  // a readable puts chars into a CharBuffer and returns the count of chars added
def readable = { it.put( "12 34" .reverse()); 5 } as Readable
 
// the Scanner constructor can take a Readable
def s = new Scanner(readable)
assert s.nextInt() == 43

    你也可以用闭包来实现方法数多于一个的接口。当调用接口中的任何方法时,这个闭包都会被调用一次。由于所有的方法都要复用这个闭包的参数表,因此典型的做法是用一个对象数组来作为底座容器。这种做法也可以用于任何Groovy的闭包,并且会把所有的参数都放在这个数组中。例如:

  interface X
{ void f(); void g( int n); void h(String s, int n); }
 
x = {Object[] args -> println "method called with $args" } as X
x.f()
x.g( 1 )
x.h( "hello" , 2 )

用Map 来实现接口

       更通用的实现多方法接口的途径是使用 Map,如下所示:

 impl = [
   i: 10 ,
   hasNext: { impl.i > 0 },
   next: { impl.i-- },
]
iter = impl as Iterator
while ( iter.hasNext() )
   println iter.next()

       上面的例子只是一个故意设计的示例,但却展示了这个概念。

       你可以仅仅实现那些真正被调用方法,但如果你调用一个Map 中未实现的方法时,将会抛出异常NullPointerException ,如:

  interface X
{ void f(); void g( int n); void h(String s, int n); }
 
x = [ f: {println "f called" } ] as X
x.f()
//x.g()    // NPE here

       需要小心的是,不要随意的用 {} 来定义 Map 。你知道下面的代码的运行结果吗?

 x = { f: {println "f called" } } as X
x.f()
x.g( 1 )

       在这里,我们实际定义的是一个带符号( Label )和代码块的闭包,由于定义了一个闭包,则所有的方法调用都会调用到这个闭包。在有些语言里,定义Map 使用的是 {} ,这很容易导致错误,因此你必须习惯 Groovy 用 [:] 定义 Map 的方式。

    在上面的例子中我们使用了“as”操作符,这就要求在用 Map 实现接口的过程中,这个接口的引用必须是静态的。如果你持有的接口引用是java.lang.class 类型的(不知道类型或写代码的时候不声明类型),此时可以使用 asType() 方法,如下所示:

def loggerInterface = Class.forName( 'my.LoggerInterface' )
def logger = [
                log : { Object[] params -> println "LOG: ${params[0]}" ; if ( params.length > 1 ) params[ 1 ].printstacktrace() },
                close : { println "logger.close called" }
              ].asType( loggerInterface )

--------------------------------------------------------------

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...