鉴于Outer
类及其Inner
类的抽象定义,我想实例化Inner1
特征中定义的具体Outer1
类。
abstract class Outer {
type Inner_Tp <: Inner;
abstract class Inner {
self: Inner_Tp =>
}
}
trait Outer1 {
self: Outer =>
protected class Inner1 extends Inner {
self: Inner_Tp =>
}
def Inner1() = new Inner1()
}
Scala编译器过早地终止编译,给出了以下错误消息:“错误:类Inner1无法实例化,因为它不符合其自身类型Outer1.this.Inner1 with Outer1.this.Inner_Tp”。的为什么吗
在抽象上下文中定义所有Inner1
类之后,它是Outer1
特征。我想推迟type Inner_Tp
的定义,直到特质混入一些具体的类。
答案 0 :(得分:7)
对于Inner1
,自我类型表示它将始终与抽象类型Inner_Tp
一起实例化。这是在实例化时未实现的承诺:类型仅为Inner1
而不是Inner1 with Inner_Tp
。
如果您需要延迟Inner_Tp
的定义,还需要延迟创建任何将其作为自我类型的实例。这是绝对必要的,因为您无法生成您还不知道的类型的值。所以最好把方法抽象化。您也可以优化抽象类型:
trait Outer1 extends Outer {
type Inner_Tp <: Inner1
protected class Inner1 extends Inner
def Inner1(): Inner_Tp
}
我不确定你的目标是什么,但你可能根本不需要自我类型(为了简洁,我把它们留了出来)。
答案 1 :(得分:1)
因为self: Inner_Tp
表示不允许实例化Inner
的子类型,除非它也是Inner_Tp
的子类型。
在self => Inner_Tp
中重写Inner1
只是重述约束,它不满足它。要获得类似的想法,当你有一个抽象类的后代时,如果它没有实现抽象方法,你必须再次写它是抽象的。你不能实现。与此相同,您重申了Inner_Tp
是必需的,您没有Inner_Tp
可用。
只要Inner_Tp
是抽象类型,您将无法将其混合,因此您将无法编写new Inner1
。您应该引入一个创建Inners的抽象方法。