Полиморфное поведение в Java

У меня есть следующий код Java,

interface A {
    int a = 5;
}

class B {
    int a = 6;
}

public class C extends B implements A {
    int b = super.a;//Line 10
    public static void main(String[] a) {
        System.out.println(new C().b);//6

    }
}

Я ожидал ошибки компилятора в строке 10, потому что компилятор не знает, на какую «а» ссылаться. Но ошибки компилятора не было. Результатом будет 6. Может ли кто-нибудь объяснить, как он принимает значение переменной экземпляра класса B (6), почему бы не использовать значение «a» интерфейса A, равное 5 ?.

Просто потому, что ты не знает, на какую переменную ссылается a, это не значит, что компилятор тоже не знает :)

Andy Turner 09.09.2018 10:01

все поля, определенные в интерфейсе, являются константами, то есть статическими и окончательными. В то время как a, определенный классом B, является полем экземпляра.

nits.kk 09.09.2018 10:51
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ключевое слово super используется для обозначения родительского класса, которым в данном случае является B. Следовательно, вы получите вывод как 6.

a, определенный в interface A, является статическим, а a, определенным в Class B, является переменной экземпляра. Следовательно, когда мы делаем super.a, это относится к значению экземпляра a, которое определено в Class B.

Если вы переименуете переменную в B, скажем, как aa, вы получите ошибку компилятора с надписью a cannot be resolved or is not a field, потому что a, определенный в interface A, не доступен напрямую в class C, потому что по умолчанию это static. Чтобы получить доступ к a, определенному в interface A, нам нужно сделать явный вызов A.a в классе C.

Если вы определите a как статический в class B и удалите super, вы получите compiler error: The field a is ambiguous

Другие вопросы по теме