C是B的子类型,B是A的子类型,所以C是A的子类型但C不是A的子类型Self 或 B 的 Self。所以你不能覆盖(在B)A的X有上限Self(即A的Self)与C不满足界限(即B的Self)。
trait A {
type Self <: A
type X <: Self
// implicitly[C <:< Self] // doesn't compile
}
trait B extends A {
override type Self <: B
// override type X = C
// implicitly[C <:< Self] // doesn't compile
}
trait C extends B {
override type Self = C
}
C的Self等于C,但这并不意味着A的Self或B的Self可以。
您可以使用下限修复编译
trait A {
type Self <: A
type X <: Self
}
trait B extends A {
override type Self >: C <: B // >: C is added
override type X = C
}
trait C extends B {
override type Self = C
}
或者,如果您的意思是 A 的 X 不是 A 的 Self 而是 C 的 Self 的子类型,您可以使用类型投影来指定它
trait A {
type Self <: A
type X <: C#Self // here
}
trait B extends A {
override type Self <: B
override type X = C
}
trait C extends B {
override type Self = C
}
我猜误会是因为defs
trait A {
def foo(): String = "A#foo()"
def bar(): String = s"bar=A#bar(), foo=${foo()}"
}
trait B extends A {
def foo(): String = "A#foo()"
}
trait C extends B {
override def foo(): String = "C#foo()"
}
当我们在A 的bar() 中写入foo() 时,我们实际上指的不是A 的foo(),而是实现的foo()。这是可能的,因为方法实现在运行时被延迟解析。但是类型是在编译时提前解决的。所以当你写
trait A {
type Self <: A
type X <: Self
}
X 上限中的Self 是A 的Self,而不是实现的Self。
OOP 原则说,在 A 内部,您将 can't refer specifically 到 C 的 foo()(除非您实例化 C)。但是您可以在任何地方专门引用A的Self,B的Self,C的Self,类型投影A#Self,B#Self,C#Self。