Overriding a method with an object
Why is it possible to override an empty-parentheses method with an object
?
trait A {
def meth = {}
def m开发者_JAVA技巧eth_p() = {}
}
class B extends A {
object meth_p
} // compiles
Overriding the method without parentheses does not compile:
class B1 extends A {
object meth
} // does not compile
Neither do any of the following combinations work (without override
modifier):
class BX extends A {
// of course, each declaration should get its own class
def meth = {}
def meth_p() = {}
def meth() = {}
def meth_p = {}
val meth = {}
val meth_p = {}
// ...
}
Is this documented and useful behaviour? I’ve just run into a very subtle bug because of this accidental override.
This sure as hell looks like a bug. If you do this the other way around it just gets weirder.
class A {
object m { override def toString = "object m" }
}
class B extends A {
def m() = "def m"
}
scala> (new A).m
res0: object A#m = object m
scala> (new A).m() // doesn't compile
scala> (new B).m
<console>:10: error: ambiguous reference to overloaded definition,
both method m in class B of type ()java.lang.String
and object m in class A of type object B#m
match expected type ?
(new B).m
^
scala> (new B).m()
java.lang.VerifyError: class B overrides final method m.()LA$m$;
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at scala.tools.nsc.interpreter.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:52)
at java.lang.ClassLoader.loadClass(Unknown Source)
at scala.tools.nsc.interpreter.AbstractFileClassLoader.scala$tools$nsc$util$ScalaClassLoader$$super$loadClass(AbstractFileClassLoader.scala:17)
at scala.tools.nsc.util.ScalaClassLoader$class.loadClass(ScalaClassLoader.scala:50)
at scala.tools.nsc.interpreter.AbstractFileClassLoader.loadClass(AbstractFileClassLoader.scala:17)
at java.lang.ClassLoader.loadClass(Unknown Source)
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Unknown Source)
精彩评论