如果接口只有一个方法,可以通过闭包,用下面的方式来实现:
// 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,如下所示:
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 ) |
--------------------------------------------------------------
总结以上是内存溢出为你收集整理的以 groovy 的方式实现接口全部内容,希望文章能够帮你解决以 groovy 的方式实现接口所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)