【问题标题】:How can I assign a val with the implementation of a trait?如何为 val 分配一个 trait 的实现?
【发布时间】:2021-05-20 18:04:29
【问题描述】:

我有以下特质和职业:

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]'。换句话说,类可以使用不同类型的参数扩展 trait A。

【问题讨论】:

  • val a: A 不适合您吗?同样在Scala中,我们使用def而不是val在超类/特征中定义一个值成员
  • 您是否希望X 的用户知道他们得到了哪个特定的A?还是应该只依赖于界面?
  • @texasbruce 它显示'必需:A,找到:G'
  • @LuisMiguelMejíaSuárez 不,他们只需要获得 A 的实现并使用 func1 和 func2。不管是G类还是F类,Z类都必须能使用func1和func2

标签: scala traits


【解决方案1】:

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

一种是让trait A类型参数covariant,这样你就可以用你在基类中声明的类型参数的子类覆盖(注意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
  }

请看这里:Sample

另一种工作方式是将 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
  }

请看这里:Sample

【讨论】:

  • 我会说最好的解决方案是使X 也通用。因为 Any 和存在式都不是很有用(通常)
猜你喜欢
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多