Scala中的压倒一切的方法
Scala允许您以2种合法方式覆盖方法:
给定超级类: class A { def a = "A" } 我们可以通过以下方式覆盖方法“a”: class B extends A { override def a = "B" } 和 class B extends A { override def a() = "B" } 两者似乎都正确地覆盖了方法“a”.这背后的设计决策是什么?为什么允许B中的“a()”覆盖A中的“a”? 解决方法
这并不总是这样(从
the language specification的变更日志):
你是正确的,这似乎是一个奇怪的设计决定,因为在无参数方法和空参数列表之间有可观察的差异.例如,假设您有以下内容: class A { def a = "A" } class B extends A { override def a = "B" } class C extends A { override def a() = "C" } 现在我们可以按照预期编写以下内容: scala> (new B).a res0: java.lang.String = B scala> (new C).a res1: java.lang.String = C 和这个: scala> (new C).a() res2: java.lang.String = C 但不是这样的: scala> (new B).a() <console>:10: error: not enough arguments for method apply: (index: Int)Char in class StringOps. Unspecified value parameter index. (new B).a() 所以Scala确实区分了两者,这显然必须体现在字节码中.假设我们编译以下内容: class A { def a = "A" } class B extends A { override def a = "B" } 然后运行: javap -verbose B > noArgList.txt 然后将代码更改为: class A { def a = "A" } class B extends A { override def a() = "B" } 重新编译并运行: javap -verbose B > emptyArgList.txt 最后检查差异: < MD5 checksum 88aeebf57b645fce2b2fcd2f81acdbbd --- > MD5 checksum 3733b3e4181b4b2f4993503d4c05770e 32c32 < #18 = Utf8 }1A! tt!ICaT-9uszaEr)"atI!!"1Q!Dg jiz"atAQ!BYt!Y G.Y11bU2bY|%M[3di")C%1A( /A$H3)!dGYtwMCQM^1nyI"AB*ue&twr --- > #18 = Utf8 }1A! tt!ICaT-9uszaEr)"atI!!"1Q!Dg jiz"atAQ!BYt! G.Y11bU2bY|%M[3di")C%1A( /A$H3)!dGYtwMCQM^1nyI"AB*ue&twr 所以有一个区别 – 两个版本的ScalaSignature注释有不同的值. 至于为什么在Scala 2.0中进行了更改:规范注意到它允许这样做: class C { override def toString: String = ... } 我的猜测是,语言设计师没有看到要求用户记住在这种情况下使用的覆盖方法的原因. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |