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 fromC
another 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 eitherC
declares 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