限制可实现Trait的类型

6

有没有可能限制可以实现trait的类型?比如说,我有一个类型

interface Something {
  void foo() 
}

以及一个特征

trait SomethingAbility {
  void bar()  {
    println "bar"
  }
}

有没有办法只允许实现该特性的类是Something类型的,例如:

// OK
class SomethingImpl implements Something, SomethingAbility {
  void foo() {
    println "foo"
  }
}

// error: this class should not be allowed to implement the trait
// because it's not a Something
class NotSomething implements SomethingAbility {
  void foo() {
    println "foo"
  }
}

一种选择是向trait添加一个抽象方法

trait SomethingAbility {
  void bar() {
    println "bar"
  }

  abstract void foo()
}

这意味着除非一个类提供了一个名为foo()的方法,否则这个特性将不能被该类实现。但是,这并不意味着该类属于Something类型。

SomethingAbility 实现 Something 接口? - cfrick
@cfrick 不是这样的......我想要确保我可以从SomethingAbility调用Something的方法,但SomethingAbility本身不需要成为一个Something - Dónal
如果它像鸭子一样嘎嘎叫... ;P 但我认为你的最后一个例子和最后一句话应该是关于抽象的 foo 而不是 bar - cfrick
1
当然,Groovy可以进行静态编译,这意味着您不能依赖鸭子类型。我已经修复了您指出的错误 - 谢谢。 - Dónal
也许我太过于深入动态领域了,但是说如果要使用SomeAbility就必须与Some混合使用,这不就等同于说SomeAb需要自己履行Some的契约,因此实现(即通过特质进行扩展)是一种有效的方法吗?在编写容易出错且容易更改的抽象方法之前,我宁愿让接口来完成这项工作。 - cfrick
我也不喜欢抽象方法的方式。我也不喜欢这种方式 SomethingAbility 实现 Something,因为需要成为 Something 的不是 SomethingAbility,而是实现该特性的类。 - Dónal
1个回答

9

我认为您要查找的是@Selftype,详见http://docs.groovy-lang.org/docs/latest/html/gapi/groovy/transform/SelfType.html。这个特性规定了使用该类的必要实现内容。因此,使用该特性的类需要:

@SelfType(Something)
trait SomethingAbility {
   void bar()  {
     println "bar"
   }
}

您声明,任何使用此特性的类也必须实现接口Something。这可以确保例如,如果您静态编译特性并从接口Something调用方法,则编译不会失败。当然,对于标准的Groovy来说,这不是必需的,因为它支持鸭子类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接