我可以在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
?
答案 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所做的事情。为了使语言变得更加复杂,必须有一些收获。