使用Scala的私有最终修饰符?

时间:2011-09-06 10:00:54

标签: scala inheritance modifier

我可以在Scala中使用private final修饰符吗?

鉴于以下代码:

1| class A { def callFoo = foo; private final def foo = "bar of A" }
2| class B extends A { private final def foo = "bar of B"}
3| println((new A()).callFoo)
4| println((new B()).callFoo)

第3行和第4行打印:

1| bar of A
2| bar of A

为什么第2行不打印bar of B是可以理解的,因为实际上有两个foo定义,B中的后者不会覆盖A中的前者。否则Scala会要求{{ 1}} - 而不是override修饰符。

那么为什么Scala不会简单地禁止修饰符final

的组合

3 个答案:

答案 0 :(得分:14)

好的,这很棘手。你的问题:“那么为什么Scala不会简单地禁止修饰符私有最后的组合?”是基于这种组合没有用的假设。

让我们说你是对的(除了细节之外,你将会在后面提到)。我不是编译人员,但从我的观点来看,“简单禁止”可能并不那么简单(至少在这种情况下)。为什么有人会尝试这样做呢?有什么权衡取舍?只是因为某些东西没用,并不一定意味着它会造成任何伤害。只是不要使用它......

现在出现了你似乎忽略的微小细节。 private修饰符是一个可见性修饰符,这意味着class B不知道它的存在。但Scala的可见性修饰符比Java更复杂。让我们假设无论出于何种原因你需要在下面的代码片段中显示代码,编译器都不会允许它。

package scope

class A {
  def callFoo = foo;
  private[scope] final def foo = "bar of A"
}
class B extends A {
  private[scope] final def foo = "bar of B"
}

object Main extends App {
  println((new A()).callFoo)
  println((new B()).callFoo)
}

这是编译器提供的错误之一:“方法foo无法覆盖最终成员”

所以你走了。 Scala只是禁止这种组合;)

答案 1 :(得分:3)

我最初认为这是为了防止在嵌套类中覆盖私有方法,但显然不是:

class A {
  private final def foo = 0

  class B extends A {
    override def foo = 1
  }
}

error: method foo overrides nothing
           override def foo = 1
                        ^

也许只是为了简化重构?因此,如果您使用final方法,请尝试将其设为private,然后发现您不需要private,这样您就不会失去final这个过程?

答案 2 :(得分:3)

解决更广泛的问题,

  

那么为什么Scala不会简单地禁止修饰符的组合   私人决赛?

这是一个新规则,并且,在那个时候,一个新的例外。它使语言更复杂,绝对没有收获。为什么没有充分理由让事情变得更复杂?

这就是Odersky不喜欢Java所做的事情。为了使语言变得更加复杂,必须有一些收获。