Наследование Java: почему не вызывается метод подкласса? - PullRequest
0 голосов
/ 25 января 2019

Мне интересно, почему Java вызывает метод подкласса с помощью метода mA (), а не с помощью метода im (b).Я действительно не вижу никакой причины, почему он это делает.Как Java решает, какой метод вызывать?

public class C {
    public static void main(String[] args) {
        A a = new B();
        B b = new B();

        a.mA();  // prints BmA
        a.im(b);  // prints Aim  --  Why not Bim?
        b.im(a);  // prints Aim  -- Why not Bim?
    }
}


public class A {
    public void mA() {System.out.println("AmA");};
    public void im(A a) {System.out.println("Aim");};
}


public class B extends A {
    public void mA() {System.out.println("BmA");};
    public void im(B b) {System.out.println("Bim");};
}

Я бы ожидал, что im (b) будет вести себя как mA ().

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Это из-за типа аргумента.

im (B b) не перекрывает im (A a)

См .: https://www.programcreek.com/2009/02/overriding-and-overloading-in-java-with-examples/

0 голосов
/ 25 января 2019

Методы im (A) и im (B) не являются переопределенными. Если вы попытаетесь аннотировать im (B) с помощью @Override, вы получите ошибку компилятора. Только методы с одинаковыми сигнатурами эквивалентны переопределению. Сигнатура метода состоит из имени и типа (ов) параметров. Типы параметров в вашем примере различны, даже если B наследует A.

Если вы хотите реализовать это, вы можете просто изменить тип параметра на Object, что имеет недостаток в том, что он не является безопасным для типа. Для безопасного решения типа вы должны использовать дженерики.

0 голосов
/ 25 января 2019

Компилятор не знает, что это экземпляр B, поэтому он не знает, что B.im(B) является кандидатом для вызова туда.

Он знает, что это экземплярA, и что существует метод с именем im, который принимает один параметр типа A;поскольку B также является экземпляром A, это метод, который он вызывает.

...