Почему вызывается метод производного класса, а не базового? java

class Super {
    public int field = 0;

    public int getField() {
            return field;
    }
}
class Sub extends Super {
    public int field = 1;

    public int getField() { // используется данный метод
        return field;
    }

    public int getSuperField() {
        return super.field;
    }
}
public class FieldAccess {
    public static void main(String[] args) {
        Super sup = new Sub();
        System.out.println(sup.field + " " + sup.getField());

        Sub sub = new Sub();
        System.out.println(sub.field + " " + sub.getField() + " " + sub.getSuperField());
    }
}

Вывод:

0 1  
1 1 0 

Ожидал:

0 0  
1 1 0

Ответы (1 шт):

Автор решения: Nowhere Man

У вас были неправильные ожидания. Так как все методы объекта в Java являются виртуальными по умолчанию (в отличие от C++/C#, где нужно явно использовать ключевое слово virtual), метод класса-потомка всегда будет виртуально перекрывать неприватный метод базового класса с тем же именем и сигнатурой и вызываться при исполнении кода.

Поэтому, если нужно обеспечить доступ к полю именно в базовом классе при помощи некого геттера, его следовало реализовать именно на уровне базового класса с модификатором final, чтобы запретить переопределение в потомке:

class Super {
    public int field = 0;

    public final int getSuperField() {
        return field;
    }

    public int getField() {
        return getSuperField();
    }
}

Тогда в потомке придётся использовать некий синоним для геттера поля из базового класса:

class Sub extends Super {
    public int field = 1;

    public int getField() {
        return field; // поле класса-потомка
    }

    // publjc int getSuperField() {} // запрещено переопределять в потомке

    public int getBaseField() { // ещё один синоним
        return super.field;
    } 
}

Ну и использование полей с одинаковыми названиями в иерархии классов, тем более открытых (с модификатором доступа public) -- признак плохого дизайна, нарушающего базовый принцип ООП -- инкапсуляцию.

→ Ссылка