overriding in Java

If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java. In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding. We can override a public or protected method in the class.  It is not possible to override a private method in a parent class since the parent method is not accessible from the child class. Just because a child class doesn’t have access to the parent method, doesn’t mean the child class can’t define its own version of the method. It just means, strictly speaking, that the new method is not an overridden version of the parent class’s method.

* The access modifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the super-class can be made public, but not private, in the subclass; Doing so will generate compile-time errors. 
* The return type must be the same or a more restrictive type, also known as covariant return types. Note covariant return types are non-primitive. so long and int are not covariant, and Number and int are not covariant. Basically, if return type is primitive, it cannot be changed. 
* An overriding method can throw any unchecked exceptions, regardless of whether the overridden method throws exceptions or not. However, the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method.
* If don’t want a method to be overridden, declare it as final. 
* we cannot override static methods because method overriding is based on dynamic binding at runtime and the static methods are bonded using static binding at compile time. It is a compile-time error if an instance method overrides a static method. When define a static method with the same signature as a static method in the base class, it is known as method hiding. 
* We cannot override private methods in Java. Private methods in Java are not visible to any other class which limits their scope to the class in which they are declared.

<b>When overriding a method, why can I increase access but not decrease it? </b>
Imagine these two classes:
```
public class Animal {
  public String getName() { return this.name; }
}
public class Lion extends Animal {
  private String getName() { return this.name; }
}
```
I could write this code:
```
Animal lion = new Lion();
System.out.println( lion.getName() );
```
And it would have to be valid, since on Animal the method getName() is public, even though it was made private on Lion. So it is not possible to make things less visible on subclasses as once you have a superclass reference you would be able to access this stuff.
<b>@Override annotation</b>
The @Override annotation is used to express that you intend for this method to override one in a superclass or implement one from an interface. You don’t traditionally think of implementing an interface as overriding, but it actually is an overriding. It so happens that the method being overridden is an abstract one.
```
class Bobcat {
  public void findDen() { }
}
class BobcatMother extends Bobcat {
  @Override
  public void findDen() { }
}
```
The following table summarizes what happens when you define a method with the same signature as a method in a superclass.
<b>Defining a Method with the Same Signature as a Superclass's Method</b>
|  | Superclass Instance Method | Superclass Static Method
|----- | ----- | -----
|Subclass Instance Method | Overrides | Generates a compile-time error
|Subclass Static Method | Generates a compile-time error | Hides