【问题标题】:Using and extended type in an overriden method在覆盖方法中使用和扩展类型
【发布时间】:2017-07-29 23:59:14
【问题描述】:

我正在尝试创建一个抽象类,该类有一个方法,我想采用与某些基类相同或扩展的参数。我以为会是:

trait InputParams
abstract class A() {
  def input[T <: InputParams](datum: T) // abstract
  ...
}

case class ExtendedInputParams() extends InputParams
class B() extends A() {
  override def input[T <: InputParams](datum: T)...
  // the input(datum) method needs more to be able to treat datum as an
  // ExtendedInputParams, how do I do this?
  ...
}

在 B 类中(我怀疑 A 也需要更改)如何将 datum 类型定义为 ExtendedInputParamsfor (new B).input(some-datum-of-type-ExtendedInputParams) 以便覆盖 input 可以将 datum 视为 ExtendedInputParams 并仍然强制执行它正在扩展InputParams?我还想强制该方法覆盖类A 中的抽象方法。

为清晰起见已更新

【问题讨论】:

  • def input[ExtendedInputParams](datum: ExtendedInputParams)... 与此def input[T](datum:T)... 相同。您正在命名类型参数。将其命名为与现有类型相同的名称会造成混淆,并表明您可能不知道自己在做什么。
  • 当你的类型参数名称隐藏类型名称时,有一个 linter 会发出警告,因为这种错误并非闻所未闻。
  • 我当然不知道自己在做什么,所以才问这个问题。
  • 在这种情况下我如何给T一个具体的类型?我以为我将具体类型传递给input 的类型参数。那我该如何声明datum的具体类型呢?
  • 更新问题更清晰

标签: scala scala-2.11


【解决方案1】:

缩小子类中的约束:

scala> class P ; class Q extends P
defined class P
defined class Q

scala> class A { type T <: P ; def f[X <: T](a: X) = a.toString }
defined class A

scala> class B extends A { type T = Q ; override def f[X <: T](a: X) = a.toString * 2 }
defined class B

scala> (new B).f(new Q)
res0: String = Q@1ea930ebQ@1ea930eb

scala> (new B).f(new P)
<console>:14: error: inferred type arguments [P] do not conform to method f's type parameter bounds [A <: Q]
       (new B).f(new P)
               ^
<console>:14: error: type mismatch;
 found   : P
 required: A
       (new B).f(new P)
                 ^

scala> (new A { type T = P }).f(new P)
res3: String = P@4300e240

改写:

scala> class P ; class Q extends P { def q = 42 }
defined class P
defined class Q

scala> class X[T <: P] { def f[A <: T](a: A) = a.toString }
defined class X

scala> class Y[T <: Q] extends X[T] { override def f[A <: T](a: A) = a.q.toString }
defined class Y

scala> (new Y).f(new Q)
res0: String = 42

【讨论】:

  • 我可能没有在上面解释清楚,为清楚起见进行了编辑。
  • B.f 收到一个Q,它扩展了P。我不小心将A 用作类型参数。
  • 就是这样,第二个例子。只是我知道我们在这里使用了 2 种类型参数,T 和 A。T 仅在声明中附加到扩展类,因此它可以在扩展类的 f 函数声明中用作边界?所以类型参数被用作类型和上限。
  • T 作为类型参数或成员在这里的工作方式相同。我认为type T = Q 更简单。你也可以def f(t: T),这取决于你在做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-14
  • 2021-09-09
相关资源
最近更新 更多