0

In the code below I have the following problem:

I don't get the semantics of

One hybrid = new Two();

My understanding is that Java performs in this case a so called upcasting. That even if hybrid is declared as an instance of One it the compiler casted it to a Two instance.

Is this correct?

Therefore at #3 it calls the method foo of Two. So far so good.

At #5 things are getting mysterious for me:

Why in earth is the compiler calling the bar method of One instead of Two? What am I missing here?

Thanks

Marcel

class One {
  public One() {}
  public String foo() {return "One-foo";}
  public String bar(One o) {return "One-bar " + o.foo();}
};

class Two extends One {
  public Two() {}
  public String foo() {return "Two-foo";}
  public String bar(Two t) {return "Two-bar " + t.foo();}
};

class Main {
  public static void main(String[] args) {
    One one = new One();
    Two two = new Two();
    One hybrid = new Two();

    System.out.println(one.foo());        // #1 One-foo
    System.out.println(two.foo());        // #2 Two-foo
    System.out.println(hybrid.foo());     // #3 Two-foo

    System.out.println(one.bar(two));     // #4 One-bar Two-foo
    System.out.println(hybrid.bar(two));  // #5 One-bar Two-foo
    System.out.println(two.bar(hybrid));  // #6 One-bar Two-foo
  }
}

I would expect the following output compared to the one below:

One-foo
Two-foo
Two-foo
One-bar Two-foo
Two-bar Two-foo
Two-bar Two-foo

The actual output:

One-foo
Two-foo
Two-foo
One-bar Two-foo
One-bar Two-foo
One-bar Two-foo
Michael
  • 41,989
  • 11
  • 82
  • 128
  • Try to use the `@Override` annotation. – Maurice Perry Feb 18 '19 at 13:07
  • 1
    The problem is that `bar(Two t)` doesn't override `bar(One o)`, it simply shadows it. – Michael Feb 18 '19 at 13:09
  • https://briangordon.github.io/2014/09/covariance-and-contravariance.html has the answers you are looking for, specifically: "Overriding methods" "If the argument types aren’t identical in the subclass then the method will be overloaded instead of overridden. You should always use the @Override annotation to ensure that this doesn’t happen accidentally." – Jan Larsen Feb 18 '19 at 13:21

1 Answers1

2

String bar(Two t) does NOT override String bar(One o).

Maurice Perry
  • 9,261
  • 2
  • 12
  • 24