我有一个不可变的容器类。
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
,我认为内部对象是下一个最好的东西。实际上,我特别想要的是Bar
和Inner
,它们分别表现为Foo
容器和SomeAbstractClass
元素,并且可以完全访问彼此&# 39;私人变量。
答案 0 :(得分:1)
由于内在object
的路径依赖性质,您要做的事情无法完成。也就是说,每次执行以下操作时:
val obj1 = new Bar(...){
def lala(inner: Inner) = ...
}
val obj2 = new Bar(...)
obj1.lala(obj2.Inner) //won't compile!!
重新定义了实际的Inner
对象。它不会编译,因为Inner
上的obj1
与Inner
上的obj2
不一样。它们不属于同一类型!
因此,您要做的是在完全确定范围和定义之前引用某事物的定义。这是编译器抱怨的原因之一。
答案 1 :(得分:0)
wheaties' answer解释了为什么这不能按照我想要的方式完成,但我想我会发布对我有类似效果的解决方案。我最后编写了一个包含Bar
和Inner
的外部类,它可以与变量上的右访问修饰符自由交互。
class BarContainer {
object Bar extends Foo[Inner.type](this.Inner) {
// Any private fields should be declared private[BarContainer]
// ...
}
object Inner {
Bar.x = 3
// ...
}
}