为什么在这个Scala代码中需要向上转换?

为什么在这个Scala代码中需要向上转换?,scala,scala-collections,upcasting,Scala,Scala Collections,Upcasting,这包括: 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 } 导入scala.collection_ 特征Foo[A,+这个 定义栏:This=(T

这包括:

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

}
导入scala.collection_
特征Foo[A,+这个
定义栏:This=(This:SortedSetLike[A,This])。空
}
但如果删除了向上转换,则无法编译:

import scala.collection._

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

  def bar: This = this.empty

}
导入scala.collection_
特征Foo[A,+这个
定义栏:This=This.empty
}

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

SortedSetLike特征继承了SetLike中的空方法

/** 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]
由于指定排序集的子类,编译器将首先找到排序集的空实现,它返回一个排序集。编译器不知道如何将生成的排序集转换为子类


但是如果你向上转换到SortedSetLike特性,编译器会发现它的空方法返回一个This

我不知道这个例子的确切细节,但这是另一个可能发生的可怕事情的例子,因为子类中的方法可能比方法签名有更具体的返回类型嘿,工具。
/** The empty set of the same type as this set
* @return  an empty set of type `This`.
*/
def empty: This