I’m learning Java and trying to understand how private, protected and public modifiers affect bindings.
I wrote this code:
public class A {
public void a() {
System.out.println("a in A.");
b();
}
private void b() {
System.out.println("b in A.");
}
public static void main(String[] args) {
B obj = new B();
obj.a();
}
}
class B extends A {
public void b() {
System.out.println("b in B.");
}
}
The output is:
a in A.
b in A.
Still, B has it’s own b method, and obj is B‘s instance. Why the output isn’t the following?
a in A.
b in B.
But if I change b method in A to the following:
public void b() {
System.out.println("b in A.");
}
the output changes to the expected:
a in A.
b in B.
So, why doesn’t b behave like virtual function when it’s declared with private keyword in A?
Because private methods (and fields) are invisible outside of the class, including to subclasses. So a private method is not part of the outside interface and cannot be overridden.
That class B declares a method of the same name with the same signature does not matter. The private method is completely invisible to B, so it might as well have a different name. The two methods have no relationship at all.
When you make the method
public(orprotected) it becomes part of the class’ API and can be overridden.It is good practice (and an IDE will do that automatically for you) to annotate all methods that you think override something with
@Override. Then the compiler will tell you if it does not (you would have gotten a compile error with this example), so this helps to catch spelling mistakes, mismatched signatures and stuff.