Complementando…
1 - O objetivo de fazer override de um método e mudar seu comportamento em relação a classe pai. Em tempo de execução o Java verifica se o método com tal nome existe na classe filha, se existir, chama ele, caso contrário, chama o da classe pai. Só é obrigatório fazer override caso o método seja abstract. Para acessar o método da superclasse em um método sobrescrito você pode usar o super.
2 - Polimorfismo. Exemplos: você tem um método que pode receber como parâmetro uma List. Não importa para o método se é uma LinkedList, umas ArrayList ou qualquer outra list, pois você pode trabalhar igualmente com elas utilizando os métodos já declarados em List. Então para não ter que fazer um monte de método com todas as possibilidades de listas possíveis (o que seria impossível, já que qualquer pessoa pode implementar List) você faz um método genérico que aceite List. Dentro de métodos você também pode fazer a mesma coisa, pois se algum dia você perceber que por exemplo ArrayList teria uma performance melhor que LinkedList, é só trocar o tipo de objeto construído, podendo manter igual todo o resto do código que utilizava esse objeto.
3 - Toda a hierarquia das classes tem que ser inicializada corretamente porque a subclasse herda todos os membros, então se por exemplo você tem um método que acessa uma variável de instância da superclasse que seria inicializada no contrutor, ela tem que ser inicializada.