Как сделать Java полиморфизм - PullRequest
0 голосов
/ 13 июня 2019

Редактировать: должно быть a2 = новый B () Я не понимаю, почему результат для a2.foo (b) равен 3 в следующем практическом вопросе.

Я думал, что при полиморфизме метод динамических типов будет работать с сигнатурой метода, которая принимает аргумент, соответствующий статическому типу.

public class A {
    public int foo(Object o) {
        System.out.println(1);
        return 1;
    }

    public int foo(A a) {
        System.out.println(2);
        return 2;
    }
}

public class B extends A {
    public int foo(A a) {
        System.out.println(3);
        return 3;
    }

    public int foo(B b) {
        System.out.println(4);
        return 4;
    }

public static void main(String[] args) {
        A a2 = new B();
        B b = new B();
        a2.foo(b);
    }
}


Ответ, который дала моя школа, - a2.foo (b) возвращает 3, однако я думал, что он вернет 4.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 13 июня 2019

a2 очевидно A, поэтому A#foo выполняется.Это возможно (компилируется и выполняется), поскольку B является экземпляром A.

Поскольку выполняется A#foo, ответом является 2 (не 3 и не 4).

0 голосов
/ 13 июня 2019

Здесь происходит две вещи:

  1. Перегрузка
  2. Перекрытие

Перегрузка означает наличие двух разных методов в одном классе с одинаковым именем, но с разными типами аргументов (поэтому они разные). Переопределение и полиморфизм означает наличие одного и того же метода в двух разных классах.

Классы A и B оба перегрузка метод foo: у них есть два метода с одинаковым именем. В A один метод принимает Object в качестве параметра, а другой - A в качестве параметра. В B в качестве параметра принимается A, а в B. Из этих четырех методов два одинаковы (foo(A)).

Метод foo(A) в B переопределяет метод foo(A) в A. Однако метод foo(B) - это другой метод.

Поэтому, когда вы вызываете a2.foo(b), вы вызываете метод foo(A). Должно быть, так как a2 объявлен как A, а A не имеет A.foo(B). Поскольку a2 на самом деле является объектом типа B, вы вызываете B.foo(A), поскольку он переопределяет A.foo(A).

0 голосов
/ 13 июня 2019

РЕДАКТИРОВАТЬ: Поскольку вопрос был изменен, ответ теперь 3, так как A.foo(A) вызывается, но переопределяется.


Если a2 было B, тогда переопределенный метод будетНикогда не используйте перегруженный метод.

Но a2 - это A, и у этого класса есть только один метод foo(A), который можно вызвать, поэтому он печатает 2

Короче говоря, только тип this в левой части . изменит выбор вызываемого метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...