Scala中的静态内部类

37

在Scala中,如何实现Java中的这个功能:

public class Outer {
  private Inner inner;

  public static class Inner {
  }

  public Inner getInner() { return inner; }
}

我特别希望我的内部类不必具有完全限定的名称 - 例如,我想要 Trade.Type ,而不是 TradeType 。因此,在Scala中,我想象它可能是这样的:

class Outer(val inner: Inner) {
    object Inner
}

但是这似乎不起作用:我的Scala Inner 从外部无法看到。当然,一个解决方案是:

class Inner
class Outer(val inner: Inner)

这是可以的 - 但由于我的类名,Inner 实际上是 Outer 的"类型",而 Outer 其实有一个很长的名称。因此:

class SomeHorriblyLongNameType
class SomeHorriblyLongName(myType: SomeHorriblyLongNameType)

这段代码非常啰嗦可读性差。我可以用Type替换掉SomeHorriblyLongNameType,但它和相关的类之间就没有明显的联系了。

5个回答

40

如果在内部类中不需要访问外部类(在Java中,如果您的内部类被声明为static,则无法访问),可以像这样操作:

object A{
    class B {
        val x = 3
    }
}
class A {
    // implementation of class here
}
println(new A.B().x)

25

正如其他人指出的那样,“static”类应该放在伴生对象内。

在Scala中,作为类成员的类、特质和对象是路径相关的。例如:

class Button {
  class Click
}


val ok = new Button
val cancel = new Button

val c1 = new ok.Click
val c2 = new cancel.Click

现在c1和c2是来自不同类的实例。其中一个类是ok.Click, 另一个是cancel.Click. 如果你想引用所有Click类的类型,可以使用Button#Click。


8
这个类是内部类,但不是静态的。 - Dmitry Zaytsev

6

来自scala-lang

在Scala中没有“静态”成员的概念。相反,Scala将类Y的静态成员视为单例对象Y的成员。

因此,似乎您可以在Object内定义一个类,但不能在类内定义静态类。


如果你在Scala类中声明一个对象,那么它就不会从该类外部可见(或者我无法弄清楚如何使其可见)。你的回答并不完全是我所问的:我问的是如何在Scala中做某件事,而不是询问Scala如何处理Java静态。 - oxbow_lakes

2

不确定我是否完全理解了您的用例... 如果可以帮助您,类内部的对象就像实例字段一样可见,例如:

case class C(var x: Int)
class A { case object b extends C(0) }
val a = new A
println(a.b.x)
a.b.x = 2
println(a.b.x)

此外,您可以通过对象完美地覆盖父级的值:
case class C(var x: Int)
class A { val y: C = C(0) }
class B extends A { override case object y extends C(2) }
val a: A = new B
println(a.y.x)

1
在Scala中,如果您需要创建一些静态方法,可以使用伴生对象,与类名相同,在其中存储所有伪静态方法。例如:
class A {
}

object A {
    def xpto // define some pseudo static methods here..
}

然后你只需要使用 A.xpto。 尝试阅读有关Scala companion模块的更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接