用闭包来实现接口
// 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 )
|
--------------------------------------------------------------
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。