开发者

Use of Scala's private final modifier?

What can I use the private final modifier in Scala for?

Given the below code:

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()).callF开发者_如何学Gooo)
4| println((new B()).callFoo)

Line 3 and 4 prints:

1| bar of A
2| bar of A

It is understandable why line 2 doesn't print bar of B because there are actually two foo definitions and the latter in B doesn't override the former in A. Otherwise Scala would require the override- instead of the final modifier.

So why does Scala not simply forbid the combination of the modifiers private final?


Ok, this is tricky. Your question: "So why does Scala not simply forbid the combination of the modifiers private final?" is based on the assumption that this combination has no use.

Let's say you are right (and you are, except for a tiny detail, which will be mentioned later). I'm not a compiler guy, but from my point of view "simply forbid" is probably not that simple at all (at least in this case). And why would someone attempt to do it? What are the trade-offs? Only because something is not useful does not necessarily mean that it does any harm. Just don't use it...

Now here comes the tiny detail you seem to have overlooked. The private modifier is a visibility modifier, which means class B is unaware of it's existence. But Scala's visibility modifiers are a bit more complex, than say, Java's. Let's assume that for whatever reason you would require code shown in the following code snippet, the compiler will not allow it.

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)
}

This is one of the errors provided by the compiler: "method foo cannot override final member".

So here you go. Scala simply forbids this combination ;)


Addressing the wider question,

So why does Scala not simply forbid the combination of the modifiers private final?

That's a new rule, and, at that, a new exception. It makes the language more complex, and at absolutely no gain. Why make things more complicated for no good reason?

That's the kind of thing Java does which Odersky dislikes a lot. For the language to become more complex, there must be some gain.


I initially thought it was to prevent overriding private methods in nested classes, but apparently not:

class A {
  private final def foo = 0

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

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

Perhaps it's just to simplify refactoring? So if you have a final method, try to make it private, and find you need it not to be private after all, you won't lose finality in the process?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜