Java - какая функция вызывается, когда все наследование, полиморфизм, перегрузка и переопределение задействованы? - PullRequest
1 голос
/ 18 марта 2019

У меня есть этот вопрос, касающийся наследования, полиморфизма, перегрузки и переопределения.Я понимаю все эти термины, но не уверен, как они работают здесь.Вот код:

class A {
    public String show(D obj) {return "A and D";}
    public String show(A obj) {return "A and A";}
}
class B extends A {
    public String show(B obj) {return "B and B";}
    public String show(A obj) {return "B and A";}
}
class C extends B{}
class D extends B{}
public class whatever {
    public static void main(String[] args) {
        A a = new B(); // note the B here
        B b = new B();
        C c = new C();
        D d = new D();
        System.out.println(a.show(a)); // B and A
        System.out.println(a.show(b)); // B and A
        System.out.println(a.show(c)); // B and A
        System.out.println(a.show(d)); // A and D
    }
}

Итак, задача здесь - найти выход.У меня уже есть ответы, это комментарии, которые я поставил.

Я понимаю первый, потому что Java автоматически выполняет динамическое связывание, поэтому a.show () вызывает show () из класса B, а a имееттип A, так что B.show (A obj) вызывается.

Последний тоже имеет смысл, метод show () перегружен и, поскольку d относится к типу D, вызывается A.show (D obj).который унаследован от класса А.

Два других, с которыми у меня проблемы.Хорошо, я понимаю, что это имеет смысл, потому что b и c оба являются объектами типа A технически, но почему это идет с "B и A" над "B и B"?

Ответы [ 2 ]

3 голосов
/ 18 марта 2019

Заявленный тип a равен A.

A имеет только два метода: один принимает A (и b и c являются экземплярами A), а другой принимает D (и ни b, ни c не являются экземплярами D).

Итак, первый метод соответствует, а второй нет.Таким образом, первый метод выбирается компилятором.

Этот метод переопределяется в B, а конкретный тип a - это B, поэтому печатается "B and A".

Метод B.show(B) не переопределяет метод A.show(A), поскольку он не принимает тот же тип, что и аргумент.

1 голос
/ 18 марта 2019

Здесь есть две концепции: одна - перегрузка, а другая - переопределение.Когда вы создаете A a = new B ();это означает, что объект B и имеет тип A.Поэтому, когда выполняется a.show (a), он сначала встречает метод show (A obj) и show (B obj) класса A, а затем сопоставляет параметр с типом A, но «a» является экземпляром B, поэтому метод show (A)obj) класса B.

Теперь, когда a.show (c) выполняется, он сначала встречается с методами show (A obj) и show (B obj) класса A, а затем не находит соответствияс параметром типа C внутри класса A, но все же он выполняется, потому что класс C расширяет B, а B расширяет A.

Короче говоря, мы можем сказать, что a.show (a) эквивалентен a.show (b) и эквивалентно a.show (c).

...