Scala特征和结构类型: can a trait extend a structural type and then call super?

标签 scala

我想拥有一个特征,可以将a)使用特定方法混合到任何类中,并且b)可以调用super。像这样的东西:

  // A and B are from a library that I don't control.  No changes allowed here.
  class A {
    def stuff = "a stuff"
  }
  class B {
    def stuff = "b stuff"
  }

  // My code starts here

  type HasStuffMethod = {
    def stuff: String
  }

  // Note that this doesn't compile - gets:
  //   class type required but AnyRef{def stuff: String} found
  trait ImplementsStuff extends HasStuffMethod {
    override def stuff = "trait + " + super.stuff
  }

  val a = new A with ImplementsStuff
  assert(a.stuff == "trait + a stuff")

  val b = new B with ImplementsStuff
  assert(b.stuff == "trait + b stuff")

有什么办法吗?

注意,我不控制A和B。它们来自另一个我无法修改的库。

[编辑-在看到答案后添加]

有没有办法像这样调用原始方法?
  trait ImplementsStuff {
    this: HasStuffMethod =>
    abstract override def stuff = "foo" + "how do I call the original method here?"
  }

这没有用,因为当您将其混合成某种东西时,它会给出:

error: overriding method stuff in class A of type => java.lang.String; method stuff in trait ImplementsStuff of type => java.lang.String cannot override a concrete member without a third member that's overridden by both (this rule is designed to prevent ``accidental overrides'')



但这不是偶然的。是的,我确实希望您跨过现有方法。然后,我也称呼它。

最佳答案

我可以想到两种选择:

选项1,使用自类型注释并从新方法(我想象中称为stuff)中调用callStuff,而不是覆盖它。

  trait ImplementsStuff  {
    this: HasStuffMethod =>
    def callStuff = "trait + " + this.stuff
  }

  val a = new A with ImplementsStuff
  assert(a.callStuff == "trait + a stuff")

  val b = new B with ImplementsStuff
  assert(b.callStuff == "trait + b stuff")

选项2(因为您说您不控制A和B)是亲爱的旧装饰器模式。
  trait HasStuff { def stuff: String }

  class DecorateStuff(decorated: HasStuffMethod) extends HasStuff {
    def stuff = "trait + " + decorated.stuff
  }
  val decA = new DecorateStuff(new A)
  assert(decA.stuff == "trait + a stuff")

  val decB = new DecorateStuff(new B)
  assert(decB.stuff == "trait + b stuff")

关于Scala特征和结构类型: can a trait extend a structural type and then call super?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9538728/

相关文章:

list - 如何按以下方式组合非对称列表

Scala:如何找到超过 2 个元素的最小值?

scala - 如何在我的 Play/Scala 项目中为 Swagger 的 @ApiOperation 指定 json 响应

scala - 如何确保只有一个 Akka JAR 出现在类路径上?

scala - 在 for 理解中绑定(bind)单个值

java - 斯卡拉 2.12 : What is the equivalent of Java 8 method reference for universally quantified SAM trait?

Scala 泛型,排除类型

Scala 查找输入是否是集合成员的方法

scala - 是否可以创建带有命名参数的部分应用函数?

java - Java 中的编译器即服务