Каким будет результат компиляции и выполнения данного кода?

class A {}

interface I {}

class B extends A implements I {}

public class OverloadTest {
    public static void foo(A a) { System.out.print("A"); }
    private static void foo(B b) { System.out.print("B"); }
    private static void foo(I i) { System.out.print("I"); }
    
    public static void main(String[] args) {        
        A a = new B();
        OverloadTest.foo(a);
        OverloadTest.foo((I) a);
    }

}
Explanation
При перегрузке(overloading) методов решение о том какой именно метод будет вызван принимается на этапе компиляции, в отличие от полиморфизма когда это делается в процессе выполнения.
1: А теперь рассмотрим OverloadTest.foo(a). Компилятор не знает на какой именно объект типа A будет ссылаться переменная 'a', компилятор только знает тип переменной 'a', а именно A. Исходя из типа переменной компилятор принимает решение вызвать метод foo(A a).
2: OverloadTest.foo((I) a). В этом случае компилятор получает явное указание, что аргумент имеет тип I, следовательно будет вызван foo(I i).

Отдельный случай это когда аргумент указан как null, т.е. OverloadTest.foo(null). В этом случае будет вызван метод с аргументом имеющим тип наиболее высокий в иерархии, т.е. в данном случае foo(B b).

Следи за CodeGalaxy

Мобильное приложение Beta

Get it on Google Play
Обратная Связь
Продолжайте изучать
тесты по Java
Cosmo
Зарегистрируйся сейчас
или Подпишись на будущие тесты