Scala实现抽象基础并在匿名类中混合特征

时间:2018-01-21 16:28:50

标签: scala traits anonymous-class

假设:

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

我能做到:

new C with T with U show

但是,它“感觉”(考虑到Scala倾向于缩短语法和一般的匿名内容),就像我可以从匿名形式实例化我的混合类。

的内容
// doesn't work like this at least:
val a = new { def show { print("Anon")}} with T with U
a show

但我完全没有确定我是否只是使用了错误的语法,或者这是不可能的。有人能告诉我应该怎么做,或者肯定是不可能的?

2 个答案:

答案 0 :(得分:2)

我认为这是不可能的。

以下两个提案尽可能接近。

将构造函数与Mixins一起使用

以下解决方案需要额外的帮助程序类D, 但最终的结果几乎就像你的虚构语法,除了 你需要一个额外的D字符,你必须这样做 使用圆括号而不是花括号:

import scala.language.postfixOps

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

new C with T with U show

class D(s: => Unit) extends A {
  def show = s
}

// that's pretty close, isn't it?
val a = new D(print("hurray!")) with T with U
a show

只需在一个区块中隐藏课程

如果您不想使用仅使用一次的类来丢弃命名空间,那么只需将该类封装在一个块中:

val a = {
  class D extends A {
    def show = println("NoPollution")
  }
  new D with T with U
}
a show

你想要的是消除无用的变量D"在上面的#class; class-valued compile-time-evaluated-expression"中,但我不知道如何做到这一点。

答案 1 :(得分:0)

这不是你想要的吗?

val a = new T with U {override def show { print("Anon")}}

语法与声明一个新类几乎完全相同,首先是扩展/混合,然后是主体。