Since, as we have seen in the previous section, class (or static) members cannot override each other but only hide, we can talk about overriding instance members, only. We have also already established that instance fields hide each other and the rules of field hiding are quite different from the much simpler rules of method overriding, so the best practice would be to not expose instance fields and access their values via getters and setters only. This way, instance member overriding is reduced to instance method overriding, and that is what we are going to describe in this section.
The rules for instance method overriding are not different than the rules for interface default method overriding: a method in a child class overrides the method in a parent class with the same signature. If the signatures are different, but the method name is the same, the method is overloaded, not overridden. So, if you would like to override a method, it is always advisable to add the @Override annotation to the method to make sure it is not just overloaded silently.
As we have established earlier, too, a static method in a child class cannot override an instance method from the parent class. It makes class instance overriding rules much simpler than interface overriding rules.
One important feature to note is that constructors, although they look like methods, are not methods or even members of the class. A constructor doesn’t have a return type and has the same name as the class. Therefore, a constructor cannot be overridden, but it can be overloaded. Its only purpose is to be called when a new instance of the class (object) is created.
With that, we move to the last subsection of the Overloading, overriding, and hiding section: instance method overloading.