An example:
public class Base {
public void saySomething() {
System.out.println("Hi, I'm a base class");
}
}
public class Child extends Base {
@Override
public void saySomething() {
System.out.println("Hi, I'm a child class");
}
}
Now assume we have a main function somewhere...
public static void main(String [] args) {
Base obj = new Child();
obj.saySomething();
}
When this runs, it will call Child's version of saySomething, because you overrode the parent's version by giving a new version of the function in Child.
The @Override annotation allows other developers (and you, when you forget) to know that this method overrides something in a base class/interface, and it also allows the compiler to yell at you if you're not actually overriding anything in a base class. For example, if you got the number of arguments wrong for a function, the compiler will give you an error saying your @Override is incorrect.
For example:
public class Child extends Base {
@Override
public void saySomething(int x) {
System.out.println("I'm a child and x is: " + x);
}
}
The compiler will yell at you because this version of saySomething takes an argument, but the parent's version doesn't have an argument, so you're @Override-ing something that's not in the parent.
On super
The Child version of saySomething will not invoke the Base version, you have to do it yourself with super.method().
For example:
public class Child extends Base {
@Override
public void saySomething() {
super.saySomething();
System.out.println("I'm also a child");
}
}
If you ran the main and used this Child class, it would print out I'm a base and I'm also a child.