For a while now , I thought overriding was , well overriding , where you  override a method on a super class with your method with the same  method signature. It was only when I've read about overriding's formal  definition on the JLS when I realized that this was only 
partially true.
This article has the following sub-topics :
[I]  formal definition of overriding
[II] hiding
[III] rules for hiding and overriding
[I] Formal definition of overriding
The JLS states that :
An instance method m1 declared in a class C overrides another instance method, m2,
declared in class A if all of the following are true:
-  C is a subclass of A.
 
-  The signature of m1 is a subsignature (§8.4.2) of the signature of m2.
 
-  Either:
 
-  m2 is public, protected, or declared with default access in the same package as C, or
 
-  m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, such that m3
 
- overrides m2.
 
Moreover,  if  m1  is  not  abstract,  then  m1  is  said  to  implement  any  and  all
declarations of abstract methods that it overrides.
Let's dissect this to see what we can get :
An instance method m1 declared in a class C overrides another instance method, m2,
declared in class A if all of the following are true:
 The definition specifically stated  that overriding are for 
 instance methods .
  So what are these methods? simple :P non-static methods (very noob indeed) 
( This is the key in differentiating 
overriding over
 hiding )
From  here on out we've narrowed down the scope of overriding . We just have  to keep in mind that overriding are for non-static methods
The code above would print :
test overriding [ baby]
It's  pretty obvious that the methods that you would override are from you're  superclass, so I guess I'll proceed with the next statement
The signature of m1 is a subsignature (§8.4.2) of the signature of m2.
How could you determine that a method is a subsignature of the other? The JLS states :
The signature of a method m1 is a subsignature of the signature of a method m2 if
either:
• m2 has the same signature as m1, or
• the signature of m1 is the same as the erasure of the signature of m2
Two methods have the same signature if they have the same name and argument
types
oh  oh :D so first we only need to worry about non-static methods, now what  the JLS is saying is  We   should always remember that overriding is  about methods having the same signatures, anything else is not  overriding ( huwow stating the obvious haha)
see code below as an example:
The method 
print with  the ellipses , is not overriding the print method on class A ( Yeah I  hear you back there, and yes I admit I'm noob lol , and yeah I know it's  overloading)
The next statements after that are boring to discuss lol.
I bet by now you have the following questions in mind,
Q.1 what will happen if the method from the parent class is 
static and your overriding method is   
non static?
Q.2 what if the method from parent class is 
non-static and the the  overriding method is 
static?
Q.3 and what if the overriding and  the overridden method are both static?
We have the following answers
Q.1 what will happen if the method from the parent class is static and your overriding method is   non static?
public class C extends A{
//instance method, this is overriding
public void print(String x ){
System.out.println(x + " [baby] " ) ;
}
public static void main (String [] args) {
C c = new C () ;
c.print ("test overriding");
}
}
class A {
//isntance method
static public void print(String x ){
System.out.println(x + " [mama] " ) ;
}
}
A.1. This would result into a compile time error . (overridden method is static)
Q.2 what if the method from parent class is non-static and the the  overriding method is static?
public class C extends A{
//instance method, this is overriding
public static void print(String x ){
System.out.println(x + " [baby] " ) ;
}
public static void main (String [] args) {
C c = new C () ;
c.print ("test overriding");
}
}
class A {
//isntance method
public void print(String x ){
System.out.println(x + " [mama] " ) ;
}
}
A.2. Same with the first answer, it would produce a compile time error. ( Overriding method is static )
Q.3  - what if the overriding and  the overridden method are both static?
public  class C2 extends A2{
//class method
public static void print(String x ){
System.out.println(x + " [baby] " ) ;
}
public static void main (String [] args) {
C2 c2 = new C2 () ;
c2.print ("test hiding");
}
}
class A2 {
//class method
public static void print(String x ){
System.out.println(x + " [mama] " ) ;
}
}
A.3 The code would compile, but this is actually not overriding , this one is called 
hiding. Yes that's the difference , you're probably cursing yourself by now knowing that It's the sole difference lol  :))
overriding = non-static
hiding = static :)
[II] Hiding 
So basically, Hiding is overriding , except that you use this for static methods
Well that one went well :))
[III] rules for hiding and overriding 
We still have these lingering questions in mind  ( since we mentioned that only the method signatures should be the same ) :
Q.1 What if they have different return types?
Q.2 What if the overridden method is throwing an exception?
Q.3. What if they have different access modifiers?
Q.4 Why am I still writing this blog entry? LOL
Q.1 What if they have different return types?
A.1 This is allowed , provided that the overriding method's return type is 
return-type-substitutable for the overridden method
. 
you  didn't see that coming huh? :D all this technical words are getting  into you're head huh? makes you wanna scratch your head huh? lol (corny  mo bert). how can a lone soul like me determine if a return type is 
return-type-substitutable?
JLS! Basa!
A method declaration d1 with return type R1 is return-type-substitutable for another
method d2 with return type R2, if and only if the following conditions hold:
-  If R1 is void then R2 is void.
 
-  If R1 is a primitive type, then R2 is identical to R1.
 
-  If R1 is a reference type then:
 
-       R1  is  either  a  subtype  of  R2  or  R1  can  be  converted  to  a  subtype  of  R2  by            unchecked conversion (§5.1.9), or
 
-      R1 = |R2|
 
 If R1 is void then R2 is void. The  code below fairly displays this rule. if you have a void return type on  the parent class' instance method, you're overriding method should also  be void. The code below would generate a compile time error (Attempting to use incompatible return types)
class A {
//isntance method
public int print(String x ){
System.out.println(x + " [mama] " ) ;
}
}
public class C extends A{
//instance method, this is overriding
public void print(String x ){
System.out.println(x + " [baby] " ) ;
}
public static void main (String [] args) {
C c = new C () ;
c.print ("test overriding");
}
}
 If R1 is a primitive type, then R2 is identical to R1
We  all know the primitives, int , short, long, double , float etc. , So  the rule is that , they should always be identical (just like the rule  about void return types ) , The code below would generate a compile time  error (Similar to those on the previous code example)
class A {
//isntance method
public double print(String x ){
System.out.println(x + " [mama] " ) ;
return 1;
}
}
public class C extends A{
//instance method, this is overriding
public int print(String x ){
System.out.println(x + " [baby] " ) ;
return 1;
}
public static void main (String [] args) {
C c = new C () ;
c.print ("test overriding");
}
}
 If R1 is a reference type then:
-       R1  is  either  a  subtype  of  R2  or  R1  can  be  converted  to  a  subtype  of  R2  by            unchecked conversion (§5.1.9), or
 
-      R1 = |R2|
 
to give you an example of the rule regarding R1 being a subtype of R2, refer to the code below:
the code would compile just fine. however if we change the return type of the method in C3. we would get a compile time error stating that we are attempting to use incompatible return type:
Q.2 What if the overridden method is throwing an exception?
An overriding class is only allowed to throw an exception that is not new or that is not broader than the exception.
Consider the following code :
The code would compile just fine, but if we interchange the exception types on the overriding and overridden methods we would get the following compile time error:
Q.3. What if they have different access modifiers?
The overriding  instance method's access modifier  should be less restrictive than the instance method that we are trying to override. 
the order of the access modifiers based on restriction is as follows ( descending )
- private
 
- default
 
- protected
 
- public.
 
You could check the example below to understand further :
IF you try to use public on the parent class, and use a private access modifier on the child class, you would get the following exception :
Q.4 Why am I still writing this blog entry? LOL
be passionate on what you do and everything else will follow.