class X1
{
private final void show() { ... }
}
class X2 extends X1
{
private final void show() { ... }
}
Question 1
The code is compiling without any errors. Since the final keyword prevents methods from being overidden, why does the code compile?
Question 2
If I remove the private keyword from both show methods, the code doesn’t compile as expected. Why?
In X2, the method is not the same method, it’s shadowing the method in X1. Since the method in X1 is private, X2 has no awareness of it and thus is able to reuse the method signature. So, when you have an X2 object and you call show, it will use X2’s show. When you have an X1 object, it will use X1’s show.
If you used the @Override annotation on X2, it would give a warning that the method to be overridden doesn’t exist (or error, not 100% sure).
This is obviously not a good idea to use the same method signature as someone looking at it later could get very confused and it definitely doesn’t make clear your intentions.