假设我有这个Scala代码:
object Outer {
object Inner {
val B = "B"
}
class Inner {
def b = B
}
}
我希望这可以编译,但B
的定义无法访问b
。我需要在import Inner._
中添加class Inner
才能使其正常运行。这是为什么?配对对象Inner
未正确定义吗?
答案 0 :(得分:11)
如果伴随对象的成员将被导入到类中,它将污染类的命名空间,而程序员无法控制它。这可能不是那么糟糕(但仍然很糟糕)的值,但我真的不希望看到与功能。
只需考虑apply()
或从特征中继承的函数(这两种情况都不能只是在不丢失的情况下更改名称)。如果这些函数自动导入到类命名空间中,编译器就不知道要使用哪个函数。因此,如果类和对象具有函数func()
,您最终会在类代码中编写this.func()
,以确保调用哪一个。
因此,可以将命名空间保持清洁。您仍然可以使用import Inner._
答案 1 :(得分:6)
这不应该以这种方式工作 - 使用import Inner._
是一致的行为。
通常,如果要在Java中实现类似于静态成员的行为,则需要伴随对象。 Scala方法是将所有静态成员移动到单个对象,其好处是可以从中访问协同类的私有/受保护成员:
object Outer {
object Inner {
def print(inner: Inner) = inner.B // compiles!
}
class Inner {
private val B = "B"
}
}
您可以将伴随对象用作具有私有构造函数的类的工厂:
scala> object Outer {
|
| object Inner {
| def newInstance = new Inner()
| }
| class Inner private() {
| private val B = "B"
| }
| }
defined module Outer
scala> Outer.Inner.newInstance
res1: Outer.Inner = Outer$Inner@431693
scala> new Outer.Inner
<console>:7: error: constructor Inner cannot be accessed in object $iw
new Outer.Inner
^