首页 > 解决方案 > 如何为 val 分配一个 trait 的实现?

问题描述

我有以下特征和类:

trait A{
  def func1: String
  def func2: Int
}
class F extends A{
  def func1: String = ???
  def func2: Int = ???
}
class G extends A{
  def func1: String = ???
  def func2: Int = ???
}

我想创建以下特征和类:

trait X{
  val a: ***
}
class Z extends X{
  override val a = new G
}

我需要在 trait X 中的 '***' 上写什么,以便我可以将 val a 分配给 F 或 G 类?谢谢你。

编辑

抱歉,我忘了说特征 A 是 A[Any],特征 F 和 G 可以是 'F extends A[String]' 和 'G extends A[Int]'。换句话说,类可以使用不同类型的参数扩展特征 A。

标签: scalatraits

解决方案


关于。您的编辑,您的代码失败,因为特征 A 仅采用固定类型的类型参数。如果您声明基类具有A[Any],则不能用A[Int]或覆盖它A[String]。有两种方法可以使您的代码正常工作。

一种是制作 trait A 类型参数covariant,以便您可以使用您在基类中声明的类型参数的子类覆盖(注意+in trait A 定义):

  trait A[+T]
  class F extends A[String]
  class G extends A[Int]
  
  trait X {
    val a: A[Any]
  }
  
  class Z extends X {
    val a = new G
  }

见这里:样品

另一种工作方式是将 a 声明为A[_](_意味着它将任何类型作为参数,这与Any) 不同:

  trait A[T]
  class F extends A[String]
  class G extends A[Int]
  
  trait X {
    val a: A[_]
  }
  
  class Z extends X {
    val a = new G
  }

见这里:样品


推荐阅读