mik*_*ent 2 groovy closures subclass
...特别是在Groovy中(因此标记)?
在Java中,您无法执行此操作...但是在动态语言(例如Python)中,您通常可以执行此操作。
given在Eclipse中尝试执行Spock功能块(即测试方法)中的操作的尝试:
Groovy:此处不期望类定义。请在适当的地方定义课程,或者尝试使用块/关闭。
...一个“合适的”地方显然不在功能范围之内。这将是笨拙而不是笨拙的。在使用Groovy几个月后,我感觉到Groovy应该何时提供groovier。
因此,说我想扩展我的abstract类AbstractFoo并创建一个新的子类Foo,在我的功能中,有什么方法可以“使用块/关闭”来实现类似的功能?
您可以通过实例化AbstractFoo并提供抽象方法的内联实现来简单地创建一个匿名类。考虑以下示例:
abstract class AbstractFoo {
void bar() {
println text()
}
abstract String text()
}
def foo1 = new AbstractFoo() {
@Override
String text() {
return "Hello, world!"
}
}
def foo2 = new AbstractFoo() {
@Override
String text() {
return "Lorem ipsum dolor sit amet"
}
}
foo1.bar()
foo2.bar()
Run Code Online (Sandbox Code Playgroud)
无论foo1和foo2实施AbstractFoo,他们提供了不同的实现text()方法导致不同的bar()方法行为。运行此Groovy脚本将向控制台产生以下输出:
Hello, world!
Lorem ipsum dolor sit amet
Run Code Online (Sandbox Code Playgroud)
这与Groovy无关,您可以使用Java实现完全相同的行为。但是,您可以通过将闭包强制转换为AbstractFoo类来使其更加“时髦” :
def foo3 = { "test 123" } as AbstractFoo
foo3.bar()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,返回“测试123”的闭包为抽象text()方法提供了一种实现。如果您的抽象类只有一个抽象方法,则它的工作原理如下。
但是,如果一个抽象类有多个我们要动态实现的抽象方法,会发生什么呢?在这种情况下,我们可以将这种方法的实现作为映射提供,其中键是抽象方法的名称,值是提供实现的闭包。让我们看下面的例子:
abstract class AbstractFoo {
abstract String text()
abstract int number()
void bar() {
println "text: ${text()}, number: ${number()}"
}
}
def foo = [
text: { "test 1" },
number: { 23 }
] as AbstractFoo
foo.bar()
Run Code Online (Sandbox Code Playgroud)
本示例使用具有两个抽象方法的抽象类。我们可以通过将类型映射Map<String, Closure<?>>到AbstractFoo类来实例化该类。运行此示例将向控制台生成以下输出:
text: test 1, number: 23
Run Code Online (Sandbox Code Playgroud)
Groovy还允许您使用GroovyClassLoader.parseClass(input)方法从多行字符串创建类。让我们看下面的例子:
abstract class AbstractFoo {
void bar() {
println text()
}
abstract String text()
}
def newClassDefinitionAsString = '''
class Foo extends AbstractFoo {
String text() {
return "test"
}
}
'''
def clazz = new GroovyClassLoader(getClass().getClassLoader()).parseClass(newClassDefinitionAsString)
def foo = ((AbstractFoo) clazz.newInstance())
foo.bar()
Run Code Online (Sandbox Code Playgroud)
在这里,我们定义了一个非匿名类Foo,该类可以扩展AbstractFoo并提供test()方法的定义。这种方法很容易出错,因为您将新类定义为String,所以在捕获错误和警告时,请不要考虑任何IDE支持。
您最初提出的问题是有关在given:Spock块中尝试为规范创建类的尝试。我强烈建议使用最简单的可用工具-创建一个嵌套的私有静态类,这样您就可以在测试中轻松访问它,并且不会在测试之外公开它。像这样:
class MySpec extends Specification {
def "should do something"() {
given:
Class<?> clazz = Foo.class
when:
//....
then:
///....
}
private static class Foo extends AbstractFoo {
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |