有没有办法在Groovy中继承接口方法注释? (@Delegate可能出现故障)

时间:2015-06-15 13:27:57

标签: inheritance methods groovy interface annotations

我的示例是使用Koshuke args4j's @Option注释完成的,但同样适用于任何其他方法注释。只是为了澄清,这个注释可以与字段或setter一起使用。

它的工作原理如下:

class AnOptionExample {
    @Option(name = '-text')
    String text
}

测试用例:

def 'recognises option from simple object'() {
    given:
    def options = new AnOptionExample()
    def parser = new CmdLineParser(options)

    when:
    parser.parseArgument('-text=whatever')

    then:
    options.text == 'whatever'
}

现在假设我想在接口级别上进行注释,然后重新使用@Option定义以及具有多种继承,这将允许我们使用不同的选项集的不同接口(简化)示例):

interface Credentials {
    @Option(name = '-username')
    void setUsername(String username)

    @Option(name = '-password')
    void setPassword(String username)

    String getUsername()

    String getPassword()
}

class CredentialsImpl implements Credentials {
    String username
    String password
}

显示失败的测试用例:

def 'does not recognise option from interface'() {
    given:
    def options = new CredentialsImpl()
    def parser = new CmdLineParser(options)

    when:
    parser.parseArgument('-username=John', '-password=qwerty123')

    then:
    def ex = thrown(CmdLineException)
    ex.message == '"-username=John" is not a valid option'
}

嗯,接口的方法注释不是继承的。足够公平 - 这是Java方式,但Groovy怎么样?以下是一些希望:

class SomeOptionsWithDelegate {
    @Delegate(methodAnnotations = true)
    final Credentials credentials = new CredentialsImpl()

    @Option(name = '-url')
    String url
}

表示奇怪的测试用例:

def 'does recognise option from interface via @Delegate'() {
    given:
    def options = new SomeOptionsWithDelegate()
    def parser = new CmdLineParser(options)

    when:
    parser.parseArgument('-username=John', '-password=qwerty123', '-url=http://auth.plop.com')

    then:
    with(options) {
        username == 'John'
        password == 'qwerty123'
        url == 'http://auth.plop.com'
    }
}

令人惊讶的是@Delegate(methodAnnotations = true)仍然有效,尽管完成委托的对象实例没有注释 - 只有Credentials接口有它们。并且没有方法注释继承...哦等等,实际上这就是重点。这似乎是个小故障。为什么@Delegate能够在CredentialsImpl未继承的情况下获取接口级别上声明的注释?

另一方面,我希望具有这样的行为作为一个功能,所以我不需要在这里使用委托,而是像:

@InheritInterfaceMethodAnnotations
class SomeOptionsViaInterface implements Credentials {
    String username
    String password

    @Option(name = '-url')
    String url
}

上述示例的明显相关测试用例将以与第二个示例相同的方式失败。因此问题是:有没有像我编写的虚构注释 - @InheritInterfaceMethodAnnotations可用? 可以实现考虑@Delegate故障。因为它似乎是有用的功能,也许有人已经做到了。如果没有,欢迎任何建议如何自行实施。

1 个答案:

答案 0 :(得分:0)

你应该研究traits他们是处理这种情况的Groovy方式。它有点像扩展一个类,但你可以根据自己的需要使用尽可能多的特性。有方法重叠的规则,以及确定调用哪种特征的方法的方法。您的注释也应该有效。

?

它们也可以在运行时添加到对象中

trait Credentials {
    String username

    @Option(name = '-username')
    void setUsername(String aUsername){
        username = aUsername}

    @Option(name = '-password')
    abstract void setPassword(String username)

    String getUsername() {return username}

    abstract String getPassword()
}

class CredentialsImpl implements Credentials {
    String password

    @Option(name = '-password')
    void setPassword(String password){ this.password = password}
    String getPassword() { password }
}