从构造函数

时间:2017-01-03 17:03:27

标签: scala constructor inner-classes

我有一个不可变的容器类。

class Foo[+T](val arg: T) {
  // ...
}

我想创建一个Foo的子类,它有一个内部对象作为参数。

class Bar extends Foo[this.Inner.type](this.Inner) {
  object Inner {
    // ...
  }
  // ...
}

我希望它是一个内部对象(而不是一个单独的对象)因为我确实需要访问Bar中的私有数据。然而,当我尝试编译该代码时,我得到:

Example.scala:6: error: this can be used only in a class, object, or 
class Bar extends Foo[this.Inner.type](this.Inner) {
                      ^
Example.scala:6: error: this can be used only in a class, object, or template
class Bar extends Foo[this.Inner.type](this.Inner) {template
                                       ^

是否可以使用内部对象作为参数调用超类构造函数?如果是这样,我做错了什么?

EDITED

在回应一些评论时,我想我应该提供一些更具体的细节。我的班级Foo实际上专门用作Foo[+T <: SomeAbstractClass],并且在其上定义了几个在SomeAbstractClass个实例上运行的操作。我想创建一个子类Bar,它同时表现为Foo及其基础SomeAbstractClass。由于我不能从这两个类继承Bar,我认为内部对象是下一个最好的东西。实际上,我特别想要的是BarInner,它们分别表现为Foo容器和SomeAbstractClass元素,并且可以完全访问彼此&# 39;私人变量。

2 个答案:

答案 0 :(得分:1)

由于内在object的路径依赖性质,您要做的事情无法完成。也就是说,每次执行以下操作时:

val obj1 = new Bar(...){
  def lala(inner: Inner) = ...
}
val obj2 = new Bar(...)

obj1.lala(obj2.Inner) //won't compile!!

重新定义了实际的Inner对象。它不会编译,因为Inner上的obj1Inner上的obj2不一样。它们不属于同一类型!

因此,您要做的是在完全确定范围和定义之前引用某事物的定义。这是编译器抱怨的原因之一。

答案 1 :(得分:0)

wheaties' answer解释了为什么这不能按照我想要的方式完成,但我想我会发布对我有类似效果的解决方案。我最后编写了一个包含BarInner的外部类,它可以与变量上的右访问修饰符自由交互。

class BarContainer {
  object Bar extends Foo[Inner.type](this.Inner) {
    // Any private fields should be declared private[BarContainer]
    // ...
  }
  object Inner {
    Bar.x = 3
    // ...
  }
}