Consider the following classes:
public class A {
public void foo() {
System.out.println("A.foo()");
}
public void bar() {
System.out.println("A.bar()");
foo();
}
}
public class B extends A {
public void foo() {
System.out.println("B.foo()");
}
public static void main(String[]
args) {
A a = new B();
a.bar();
}
}
The output of this code is A.bar() and then B.foo(). I've noticed that if I change the method foo()'s access level from public to private the output is: A.bar() and then A.foo().
Why?

If A.foo() is private, then it can't be overridden by a subclass - any other class should basically be unaware of the existence of private members. You can't override a member you can't "see".
From section 8.4.8.1 of the JLS:
An instance method mC declared in or inherited by class
C, overrides fromCanother method mA declared in classA, iff all of the following are true:
...
One of the following is true:
- mA is public.
- mA is protected.
- mA is declared with package access in the same package as
C, and eitherCdeclares mC or mA is a member of the direct superclass ofC.- mA is declared with package access and mC overrides mA from some superclass of
C.- mA is declared with package access and mC overrides a method m' from
C(m' distinct from mC and mA), such that m' overrides mA from some superclass ofC.
See more on this question at Stackoverflow