4
class PolymorphisomTest {

    class Base {
        public void doTest(double d) {
            System.out.println("From Base");
        }
    }

    class DerivedBase extends Base {

        public void doTest(int d) {
            System.out.println("From Derived Base");
        }
    }

    public void use(Base  base) {
        base.doTest(3);
    }
    public void run() {
        use(new Base());
        use(new DerivedBase ());
    }
    public static void main(String []cmd) {
        new PolymorphisomTest ().run();
    }
}

Here doTest(double d) from parent class and doTest(int d) from subclass but when i call base.doTest(3) it always invokes parent class method even my object reference is different. what's the reason behind it?

  • 2
    If you use the `@Override` annotation, you get a compiler error telling you that you are not *overriding* anything. – Elliott Frisch Feb 18 '17 at 06:03
  • but when base object reference is subclass that time it also invoke parent class method. why it unable to invoke sub class method as my object refer to sub class – Newaz Sharif Amit Feb 18 '17 at 06:05
  • 1
    See my answer. By changing the parameter type to `int`, you're creating a new method instead of overriding the parent class one. – qxz Feb 18 '17 at 06:08
  • Base only has one method `doTest(double)` the signature of a method called is determined at compile time, not runtime. – Peter Lawrey Feb 18 '17 at 09:13
  • Methods with different signatures don't override one another. – Peter Lawrey Feb 18 '17 at 09:14
  • This question not duplicate as that question with totally different parameters. Here OP is confused as overloaded method is better candidate. – Panther Feb 18 '17 at 13:04

3 Answers3

0

doTest(double d) is a completely different method from void doTest(int d), because they have different parameter lists. There actually isn't any polymorphism there at all; DerivedBase is declaring a new method, not overloading Base.doTest. It's as if you had done this:

class Base {
    public void doTest(double d) {
        System.out.println("From Base");
    }
}

class DerivedBase extends Base {
    public void doSomethingElse(int d) {
        System.out.println("From Derived Base");
    }
}

Changing a parameter's type changes the method signature, and makes it a new method instead of overriding the parent class' method.

When you call base.doTest(3), the compiler is going to call doTest(double), because that's the only method of the Base class that matches the parameter. Because that method isn't overriden by anything, Base.doTest gets called.

qxz
  • 3,814
  • 1
  • 14
  • 29
  • when i call base.doTest() by sub class reference then whats problem with parameter? – Newaz Sharif Amit Feb 18 '17 at 06:08
  • If you want a subclass to override a method, it must have the _exact_ same **name**, **parameter types**, and **return type**. Your subclass reference doesn't override the parent class method. – qxz Feb 18 '17 at 06:10
  • In `use(Base base)`, the method signature that will be called is determined at compile time, not based on what the actual runtime type of the object may be. Therefore, it must select the method in the base class. – qxz Feb 18 '17 at 06:12
  • i got your point. i personally believe it's a one kind of limitation of method overloading – Newaz Sharif Amit Feb 18 '17 at 06:26
0

DerivedBase class inherited your doTest from base class. Now, it has 2 methods- doTest (double d) doTest (int d)

You have not overridden method but overloaded it by giving different parameter. If you need to override doTest add method with double as parameter.

Reason why it is not calling doTest (int d) is when we call from parent reference , it searches for method their during compile time and bind with same. And at runtime , its same method with same signature from object in hand.

Panther
  • 3,312
  • 9
  • 27
  • 50
  • 1
    ok but my point is when i pass doTest(3) here 3 is int type the why it no matches in sub class method – Newaz Sharif Amit Feb 18 '17 at 06:16
  • Sorry for late answer i am in bus , so saved partial answer as bus stopped for morning break – Panther Feb 18 '17 at 06:47
  • 1
    It doesn't match the subclass method because it's called from a variable declared as the supertype. That is evaluated at compile time, as @Panther explained. So the compiler promotes the argument to `double` to fit the only matching method available _through the declared type_. That method is not overridden. – Lew Bloch Feb 18 '17 at 10:25
0

To override a method you must match the method signature in the derived class. When you change from double to int you create a new method. From Defining Methods - The Java Tutorials,

Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types.

The @Override annotation can protect you from this specific class of error. You can do something like,

class DerivedBase extends Base {
    @Override
    public void doTest(double d) {
        System.out.println("From Derived Base");
    }
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249