Why is superclass method called while that method is overriden? (from OCA practice test)

936 Views Asked by At

From question three in these OCA practice questions (pdf):

abstract class Writer {
   public static void write() {
      System.out.println("Writing...");
   }
}

class Author extends Writer {
   public static void write() {
      System.out.println("Writing book");
   }
}

public class Programmer extends Writer {
   public static void write() {
      System.out.println("Writing code");
   }
   public static void main(String[] args) {
      Writer w = new Programmer();
      w.write();
   }
}

The output is Writing....

I don't understand why. As Programmer overrides Writer's write method, I thought it should call the method in Programmer and not in Writer.

Why?

4

There are 4 best solutions below

2
Suresh Atta On BEST ANSWER

You have to understand two points here.

There is no overriding concept in case of static members. They are simply static and never change based on instance.

And static members bind to class rather than instance. So no matter what is the instance, they look the type they got called and execute.

0
Andrew Tobilko On

The type of the reference is Writer. You have called a static method for which overriding isn't applied - the method from the Writer is going to be invoked.

The mechanism is called method hiding.


Check out these cases:

new Programmer().write();             // code  [Programmer]
((Writer)new Author()).write();       // ...   [Writer]

new Author().write();                 // book  [Author]
((Writer)new Programmer()).write();   // ...   [Writer]

new Writer() {{}}.write();            // ...   [Writer]
2
Rick On

Found the answer myself.

There is no such thing as overriding a static method in Java. This is why when you call a static method from the superclass reference, the superclass static method will be called.

So

public class SuperClass {
    public static void write() {
        System.out.println("Writing Super");
    }
    public void writeMore() {
        System.out.println("super something");
    }
}
public class SubClass extends SuperClass {
    public static void write() {
        System.out.println("Writing Sub");
    }
    public void writeMore() {
        System.out.println("sub something");
    }
}
public class Test {
    public static void main(String[] args) {
        SuperClass super = new SubClass();
        super.write();
        super.writeMore();
    }
}

Will output

Writing super
sub something

If you want to call the static write() method from the subclass. You have to reference it from a subclass. E.g.:

SubClass sub = new Subclass();
sub.write();

Some sources where I learned about this: https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/ Why doesn't Java allow overriding of static methods?

0
NITIKA On

As we know, static methods cannot be overridden. If we try to do so, it turns out to be method hiding instead. In the above case, both class- Writer and Programmer contain write() method.

When Programmer extends the Writer class and provides its own implementation of the write() method, it just hides the Writer implementation of it.

Now, on runtime, the compiler just checks the Reference type (since it is a static method, compiler is not concerned about the object created to call the method. Remember, static methods are class methods). Hence, compiler checks and finds that reference w is of type Writer, it calls the Writer version of the write method instead. If the methods would not have been static, what you expect would have been the output instead.