Rocky
Rocky

Reputation: 149

Java runtime polymorphism not working with different parameter types

I have 3 different class,

public class Parent {
    public void add(double a, double b) {
        System.out.println("Parent class add(double double)");
    }

public class Child extends Parent {
    public void add(long a, long b) {
        System.out.println("Child class add(long long)");
    }
}

public class Test {
    public static void main(String arr[]) {
        Parent parent = new Child();
        parent.add((long)System.currentTimeMillis(), (long)System.currentTimeMillis());
    }
}

The output should be Child class add(long long), but instead of this, it is showing Parent class add(double double)

But when I am adding child's class's add method in parent class, it is showing correct output. Can anyone please tell me the reason.

Upvotes: 2

Views: 539

Answers (4)

Chetan Kinger
Chetan Kinger

Reputation: 15212

You are not overriding the methods in the Child class. You are overloading the inherited methods from the Parent class. Runtime polymorphism only applies to overridden methods in a subclass and not it's overloaded form.

An explanation of why this happens is as follows :

  1. The Child class inherits the public add method that takes two double arguments. Even if you can't see it in the code, the child class actually contains a public add method that takes two double arguments.
  2. When you define a method called add in Child that takes two long arguments, you are essentially overloading the inherited add method that takes two double arguments.
  3. Since run-time polymorphism is only applicable at, well, runtime, the compiler does not know at compile time that the Child class overloads the add method to take two long arguments instead. At runtime, the JVM will simply dispatch the call to the inherited add method that takes two double arguments since that's the method that the Child class overrides.

You should always add the @Override annotation above a method that you think that you are overriding from a parent class. This has two advantages

  1. You know right away when you look at a method that it is overriding a method from the super class.
  2. You get a compilation error straight away if the parent class does not contain a method with a similar signature.

Upvotes: 2

Bobby
Bobby

Reputation: 471

You are overloading not overriding here. So when you run the code you are executing against Parent.add(double,double) and your long arguments are being widened to be doubles.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5

Upvotes: 0

rgettman
rgettman

Reputation: 178243

The problem is that the method signature to be called is chosen at compile time. The compiler only knows that parent is of type Parent, so the only compatible signature is add(double, double), because both longs can be widened to be doubles.

The Child method add(long, long) is an overload, not an override, so Child inherits the add(double, double) method, and it is called.

If you add the add(long, long) method to the Parent class, then it will be an exact match and it will be called over the add(double, double) method.

Upvotes: 5

Turing85
Turing85

Reputation: 20185

You cannot access methods of subclasses when using a superclass-reference. The described behaviour is expected, since there is no method add(long, long) within Parent, but only a method add(double, double) (thus, you do not override, but overload add within Child).

Upvotes: 0

Related Questions