Groovy提供了一些非常方便的方法来实现接口
使用闭包实现接口
只有一个方法的接口可以使用闭包来实现,例如
1 |
// a readable puts chars into a CharBuffer and returns the count of chars added |
2 |
def readable = { it.put( "12 34" . reverse ()); 5 } as Readable |
3 |
4 |
// the Scanner constructor can take a Readable |
5 |
def s = new Scanner(readable) |
6 |
assert s.nextInt() == 43 |
当然也可以使用闭包来实现不止一个方法的接口.这个闭包将会被这个接口的所有的方法调用.例如:
1 |
interface X { |
2 |
void f() |
3 |
void g( int n) |
4 |
void h(String s, int n) |
5 |
} |
6 |
7 |
x = {Object[] args -> println "method called with $args" } as X |
8 |
x.f() |
9 |
x.g( 1 ) |
10 |
x.h( "hello" , 2 ) |
使用map实现接口
通常情况下,接口中都会包含多个方法,我们可以使用map来实现接口,比如:
1 |
impl = [ |
2 |
i: 10 , |
3 |
hasNext: { impl.i > 0 }, |
4 |
next: { impl.i-- }, |
5 |
] |
6 |
iter = impl as Iterator |
7 |
while ( iter.hasNext() ) |
8 |
println iter.next() |
请注意,这是一个有点做作的例子,但说明了这个概念。
你只需要实现接口中会被调用的方法, 如果你调用了一个在map中并不存在的方法的话,那么将会抛出NullPointerException 异常。 例如:
1 |
interface X |
2 |
{ void f(); void g( int n); void h(String s, int n); } |
3 |
4 |
x = [ f: { println "f called" } ] as X |
5 |
x.f() |
6 |
//x.g() // NPE here |
你能猜出下面的代码做了什么么?
1 |
x = { f: { println "f called" } } as X |
2 |
x.f() |
3 |
x.g( 1 ) |
我们在这里定义的是一个闭包,一个标签一个代码块,我们刚刚定义了一个每个接口方法都会调用的闭包, 一些语言使用{}来定义map,所以这可能误导你,请记住在groovy中定义map使用[:]。
注意:使用as操作符需要你有一个你打算使用map实现的接口的静态引用。如果你有一个代表你想实现的接口的java.lang.Class 对象的引用,你就可以如同下面的方式一样使用asType 方法:
1 |
def loggerInterface = Class.forName( 'my.LoggerInterface' ) |
2 |
def logger = [ |
3 |
log : { Object[] params -> println "LOG: ${params[0]}" ; if ( params.length > 1 ) params[ 1 ].printStackTrace() }, |
4 |
close : { println "logger.close called" } |
5 |
].asType( loggerInterface ) |
See also: