0

The question is asking what should go in place of the [???] in order to make the assertion statement at the bottom succeed. I have figured out that the answer should be "Child String". However I don't understand why when calling name() on p while passing "String" as an argument results in the overridden method name(Object b) being called as opposed to the name method that specifically takes a string as an argument?

I understand that String extends Object (I think?) but I don't quite understand why this occurs.

The code is as follows:

interface Parent {
  public String name(Object b);
}

class Child implements Parent {
  public String name(Object b) {
    return [???];
  }
  public String name(String b) {
    return "Child " + [???];
  }
}

public class Exercise {
  public static void main(String[] args) {
    Parent p = new Child();
    assert p.name("String").equals("Child String");
  }
}

Initially I thought p.name("String") would call "public String name(String b)" as the argument given to the name() method is specifically a String.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 1
    Which method is invoked is decided at compile-time. Since you've declared `p` to be `Parent`, the only method the compiler can resolve is `Parent#name(Object)` (which is legal, because `String` is an `Object`). Then, at run-time, dynamic dispatch takes place for overridable instance methods. Because `p` is _actually_ a `Child` at run-time, it's the `Child#name(Object)` method that's invoked, because that method overrides `Parent#name(Object)`. The `Child#name(String)` method is only an _overload_; it does not _override_ anything in the `Parent` interface. – Slaw Mar 10 '23 at 23:52
  • If you were to add a `String name(String b);` method to `Parent`, or if you were to declare `p` as a `Child`, then that's the method the compiler would choose, because `String` is a closer match for `"String"` than `Object` is. – Slaw Mar 10 '23 at 23:55

0 Answers0