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

Inheritance 有没有办法在Groovy中继承接口方法注释?(@Delegate中可能存在故障),inheritance,methods,groovy,interface,annotations,Inheritance,Methods,Groovy,Interface,Annotations,我的示例是使用@Option注释完成的,但这同样适用于任何其他方法注释。为了澄清,此注释可以与字段或setter一起使用 其工作原理如下: class AnOptionExample { @Option(name = '-text') String text } 以及测试用例: def 'recognises option from simple object'() { given: def options = new AnOptionExample()

我的示例是使用
@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
定义,并具有某种多重继承,这将允许对不同的选项集使用不同的接口(简化示例):

显示故障的测试用例:

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)
可以工作,尽管对其执行委托的对象实例没有注释,只有
凭证
接口有注释。并且没有方法注释继承。。。哦,等等,实际上这就是重点。这似乎是个小故障。为什么
@Delegate
能够拾取接口级别上声明的注释(如果这些注释不是由
CredentialsImpl继承的)

另一方面,我希望将这种行为作为一种特性,这样我就不需要在这里使用委托,而是像这样:

@InheritInterfaceMethodAnnotations
class SomeOptionsViaInterface implements Credentials {
    String username
    String password

    @Option(name = '-url')
    String url
}
显然,上述示例的相关测试用例会以与第二个示例相同的方式失败。因此,问题是:是否有类似于我虚构的注释-
@inheriteInterfaceMethodAnnotations
的东西可用? 考虑到
@Delegate
故障,可以执行此操作。因为这似乎是一个有用的特性,也许有人已经做过了。如果不是的话,我欢迎任何关于如何自己实现它的建议。

你应该看看它们是处理这种情况的非常好的方法。这有点像扩展一个类,但是你可以用你想要的任何特性来实现它。有方法重叠的规则,以及确定调用哪个trait的方法的方法。您的注释也应该起作用

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 }
}
它们也可以在运行时添加到对象中

def 'does recognise option from interface via @Delegate'() {
    given:
        def parser = new CmdLineParser(new Object() as Credentials )

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

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

哦,我很确定我在试验特性,我得到了与接口相同的精确结果。不过我得再看看,谢谢。
def 'does recognise option from interface via @Delegate'() {
    given:
        def parser = new CmdLineParser(new Object() as Credentials )

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

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