3

鉴于Outer类及其Inner类的抽象定义,我想实例化trait 中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 和 Outer1.this.Inner_Tp”。为什么?

毕竟Inner1类是在一个抽象上下文中定义的,这是它的Outer1特征。我想推迟 的定义,type Inner_Tp直到特征混入某个具体的类。

4

2 回答 2

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
}

我不确定你在追求什么,但你可能根本不需要自我类型(为了简洁起见,我已经把它们省略了)。

于 2011-11-21T15:57:00.543 回答
1

因为self: Inner_Tp告诉Inner除非它是的子类型,否则不允许实例化任何子类型Inner_Tp

重写只是重申约束self => Inner_TpInner1它不满足它。类似的想法,当你有一个抽象类的后代时,如果它没有实现抽象方法,你必须再次写它是抽象的。而且你无法实例化。同样在这里,你重申这Inner_Tp是必需的,你没有Inner_Tp提供。

只要Inner_Tp是抽象类型,就不能混进去,也就不能写new Inner1. 您可能应该引入一个创建 Inners 的抽象方法。

于 2011-11-21T15:58:24.973 回答