Field overriding Java vs Scala

Inheritance is one of the foundations of object-oriented programming, it sounds straight forward on paper, but when it comes down the specifics, the rules are subtly different from language to language, and I will compare and demonstrate the subtlety with field overriding in Java and Scala.

Java way

Consider this example for field overriding in Java.

public class Parent {
protected static String name = "parent";
    public String getName() {
    return this.myName();
    }
}

public class Child extends Parent {
final static String name = "child";
}

public static void Main(final String[] args) {
final Parent parent = new Parent();
final Child child = new Child();

parent.getName(); // "parent"
child.getName(); // "parent"
}

If you know Java, it's probably not hard to tell both "getName" results are "parent", and there is a legitimate reason for that, in Java, fields cannot be overridden, but can be "shadowed" in subclasses.

To expand on that, if the subclass has defined a field in the same name as in superclass, the field will hide the one in the superclass, but not overriding it. If the method in superclass is called by an instance of a subclass, the method will access the field in the superclass, instead of the one in the subclass.

So how can the field value be overridden? The answer is through method overriding.
public class Parent {
protected String myName() {
return "parent";
}

public String getName() {
return this.myName();
}
}

public class Child extends Parent {
@Override
protected String myName() {
return "child";
}
}

Scala way

This shouldn't be a surprise if you have been doing classic Java for some time, but I have to admit I was caught by this today, and I guilty as charged, because I have got quite a few years of Scala experience in my bag, and obviously the rules are a little different: both methods and fields can be overridden in Scala.
class Parent {
protected val name = "parent"

def getName: String = name
}

class Child extends Parent {
override final val name = "child"
}

(new Parent).getName // "parent"
(new Child).getName // "child"
It should be obvious that the "getName" results are respective to whichever class it's called from. And it would be fair to say there are a few rules on Scala filed overriding you should be aware as well:

  • use the override keyword to specify the field to be overridden
  • only immutable fields can be overridden, i.e. only fields specified with val
  • mutable fields can NOT be overridden, i.e. fields specified with var
  • immutable fields can NOT be overridden by mutable fields
If you can't remember these rules, don't worry, compiler will tell you when you've done something wired.

Comments

Popular posts from this blog

How to: Add Watermark to PDFs Programmatically using iTextSharp

A practical guide to Scala Traits

A Short Guide to AWK