12

这编译:

import scala.collection._

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]]
extends SortedSetLike[A, This] { this: This =>

  def bar: This = (this: SortedSetLike[A,This]).empty

}

但是,如果删除了 upcast,它将无法编译:

import scala.collection._

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]]
extends SortedSetLike[A, This] { this: This =>

  def bar: This = this.empty

}

为什么?从extends子句中我们知道那Foo是 a SortedSetLike[A, This],所以向上转换当然是有效的——但这不是表明编译器允许发生冲突继承吗?

4

1 回答 1

6

SortedSetLike trait 继承了SetLikeempty方法。

/** The empty set of the same type as this set
* @return  an empty set of type `This`.
*/
def empty: This

但是SortedSet覆盖了方法并且有一个明确的返回类型:

/** Needs to be overridden in subclasses. */
override def empty: SortedSet[A] = SortedSet.empty[A]

由于您指定ThisSortedSet的子类,编译器将首先找到SortedSetempty实现,它返回一个SortedSet。编译器不知道如何将生成的SortedSet转换为您的This子类。

但是,如果您向上转换为SortedSetLike特征,编译器将找到它的方法,该方法返回一个This

于 2015-09-10T19:47:21.723 回答