Pregunta

Why the folowing code print the string in the override method instead of the original method which should print "test"? I already use parent to point to self and use parent to call the method

class myClass {
    parent=>
    def method(a:Int):String={
       "test"
    } 
    def run={
        println(parent.method(1))
    }
}   

val testClass=new myClass {
     override def method(a:Int):String={
          "substring"
    }
}
¿Fue útil?

Solución

In your example the parent identifier is simply another name for the this object, a pointer to whatever this object is at runtime. In Scala and Java (on the JVM in general), the rules of invoking a method on an object are that the overridden method of the runtime type of the object is called. To do this, the JVM relies on virtual function tables that associate the object type and the name of a method with its specific implementation. This is unlike C++, where calling a method on an object value (not pointer or reference) will resolve the method from the compile-time type of that object.

For example, in Scala you could do:

val compileTimeVar: myClass = new myClass { override def method(a: Int) = "substring" }

From the standpoint of the Scala compiler, compileTimeVar has a type myClass. However, the runtime type is the unnamed type internally represented as something like xxx$anon$1, and this unnamed type overrides method. Calling:

compileTimeVar.method

always calls the overridden method if it exists in that runtime type - it will return "substring".

The so-called self pointer is no different from assigning the object to a variable with lost runtime type information - your code is equivalent to this:

class myClass {
  def parent: myClass = this
  def method(a: Int) = "test"
  def run = println(parent.method(1))
}

If you really want run to call the method defined in myClass and not whatever is overridden, do this:

class myClass {
  private def privateMethod(a: Int) = "test"
  def method(a: Int) = privateMethod(a)
  def run = println(this.privateMethod(1))
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top