Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between the different overriding methods in Scala?

Scala lets you override a method in two legal ways:

Given super class:

class A {
  def a = "A"
}

We can override the method "a" by:

class B extends A {
  override def a = "B"
}

and

class B extends A {
  override def a() = "B"
}

both seem to override the method "a" correctly. What is the design decision behind this? Why allow for "a()" in B to override "a" in A?

like image 660
platypus Avatar asked Sep 01 '12 21:09

platypus


People also ask

What is override method in Scala?

Scala overriding method provides your own implementation of it. When a class inherits from another, it may want to modify the definition for a method of the superclass or provide a new version of it. This is the concept of Scala method overriding and we use the 'override' modifier to implement this.

What is the difference between method overriding and inheritance?

Inheritance enable us to define a class that takes all the functionality from parent class and allows us to add more. Method overriding occurs simply defining in the child class a method with the same name of a method in the parent class .

What is the difference between method overriding and method overloading?

When the method signature (name and parameters) are the same in the superclass and the child class, it's called overriding. When two or more methods in the same class have the same name but different parameters, it's called overloading.

How do you override variables in Scala?

In scala, you can override only those variables which are declared by using val keyword in both classes.


1 Answers

This hasn't always been the case (from the change log of the language specification):

Scala version 2.0 also relaxes the rules of overriding with respect to empty parameter lists. The revised definition of matching members (§5.1.3) makes it now possible to override a method with an explicit, but empty parameter list () with a parameterless method, and vice versa.

You are correct that this seems like an odd design decision, given that there are observable differences between parameterless methods and ones with empty parameter lists. For example, suppose you have the following:

class A { def a = "A" }
class B extends A { override def a = "B" }
class C extends A { override def a() = "C" }

Now we can write the following, as expected:

scala> (new B).a
res0: java.lang.String = B

scala> (new C).a
res1: java.lang.String = C

And this:

scala> (new C).a()
res2: java.lang.String = C

But not this:

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

So Scala does make a distinction between the two, which obviously must be reflected in the bytecode. Suppose we compile the following:

class A { def a = "A" }
class B extends A { override def a = "B" }

And then run:

javap -verbose B > noArgList.txt

Then change the code to this:

class A { def a = "A" }
class B extends A { override def a() = "B" }

Recompile, and run:

javap -verbose B > emptyArgList.txt

And finally check for differences:

<   MD5 checksum 88aeebf57b645fce2b2fcd2f81acdbbd
---
>   MD5 checksum 3733b3e4181b4b2f4993503d4c05770e
32c32
<   #18 = Utf8               }1A!
                                 \t\t!ICaT-9uszaE\r)\"a\tI!!\"1Q!Dg
jiz\"a\tAQ!BY\t!Y                                                  G.Y11bU2bY|%M[3di\")C%1A(
                 /A$H3)!dGYtwMCQM^1\nyI\"AB*ue&tw\r
---
>   #18 = Utf8               }1A!
                                 \t\t!ICaT-9uszaE\r)\"a\tI!!\"1Q!Dg
jiz\"a\tAQ!BY\t!                                                   G.Y11bU2bY|%M[3di\")C%1A(
                /A$H3)!dGYtwMCQM^1\nyI\"AB*ue&tw\r

So there is a difference—the two versions have different values for the ScalaSignature annotation.

As to why the change was made in Scala 2.0: the specification notes that it allows this:

class C {
    override def toString: String = ...
}

My guess is that the language designers just didn't see a reason to require users to remember which approach the overridden methods used in cases like this.

like image 143
Travis Brown Avatar answered Oct 06 '22 00:10

Travis Brown