Basicamente o modificar final é aplicado da seguinte maneira:
- Variável: Uma variável final não pode ter o seu valor alterado
- Método: Um método final não pode ser sobrescrito
- Classe: Uma classe final não pode ser estendida
Sendo assim, é importante saber que você dever ter algumas coisas em mente antes de sair declarando tudo como final, principalmente classes e métodos, pois alguns princípios de orientação a abjetos (veja aqui e aqui) são quebrados quando esse modificador é utilizado de forma indiscriminada.
Mas também tem o outro lado, pois em muitos casos o modificador final garante a segurança, como podemos ver na classe String.
Linguagens como Ruby permitem que você mude (não sei se mude é a palavra mais apropriada) a classe String, por um lado isso é ótimo, pois garante mais flexibilidade, mas por outro lado pode ser perigoso, e exige conhecimento do que você está fazendo.
Agora vamos para as regras:
Variável Final
Uma Variável final não pode ter ser valor alterado. Sendo assim, quando declaramos uma variável assim:
|
1 |
final int var = 10; |
Não podemos alterar seu valor, e caso você tente alterar ocorrerá uma exceção, exemplo:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
class VarFinal{ public static void main(String args[]) { final int idade = 20; System.out.println(idade); idade += 1; // Erro!! } } |
Ao tentar rodar essa classe você verá a exceção: VarFinal.java:6: cannot assign a value to final variable idade.
Lembrado que se essa variável for um atributo de um objeto ela deve ter o seu valor inicializado, pois as variáveis finais não são inicializadas com valor default.
Argumento Final
Além de ser usado em variáveis, métodos e classe o modificador final também pode ser utilizado nos argumentos, e como ver em código é melhor do que em texto, vamos a mais uma classe:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
class ArgFinal { // a declaracao e bem simples public void argumentoFinal (final int idade) { /* do mesmo modo que uma variavel final se tentarmos alterar o seu valor... */ idade += 1; // Erro!! } } |
Só lembrando que também não podemos alterar o valor de um argumento final, e se você insistir em tentar o compilador reclamará: ArgFinal.java:4: final parameter idade may not be assigned
Método Final
O modificador final normalmente é utilizado em métodos importantes para o programa, e que não podem ter o seu comportamento alterado (voltamos ao exemplo da classe String), e se tentarmos sobrescrever um método final, vai aparecer uma exceção igual ao próximo exemplo:
|
1 2 3 4 5 6 7 8 |
class MaeFinal { final void imprimeOi(){ System.out.println("Oi"); } } |
|
1 2 3 4 5 6 7 8 |
class FilhaFinal extends MaeFinal { void imprimeOi() { System.out.println("Oi novo"); } } |
A classe MaeFinal compila sem nenhum problema, mas ao tentar compilar a classe FilhaFinal teremos a seguinte exceção: FilhaFinal.java:2: imprimeOi() in FilhaFinal cannot override imprimeOi() in MaeFinal; overridden method is final.
Classe Final
E finalmente, as classes finais (que trocadilho ridículo)…
As classes marcadas com o modificador final não podem ser herdadas (ter subclasses/classes filhas), sendo assim nenhuma classe pode reaproveitar as funcionalidades dela.
Bom, mas vamos ao código em Java:
|
1 2 3 |
final class MaeFinal { // variaveis e metodos } |
|
1 2 3 |
class FilhaFinal extends MaeFinal { // Erro!! } |
E mais uma vez, se tentarmos executar a classe FilhaFinal, teremos a seguinte exceção: FilhaFinal.java:1: cannot inherit from final MaeFinal.
É importante lembrar que uma classe não pode ser marcada como final e abstract ao mesmo tempo, final e abstract são praticamente o oposto, enquanto com final uma classe não pode ser estendida, com abstract ela deve ser estendida.
Chegamos ao final de mais um post, e em breve estarei escrevendo também sobre minha nova experiência com Ruby, comecei a estudar agora (claro que em “banho Maria”) e estou tendo uma boa impressão, e não é só outra linguagem de programação, é um novo conceito (outro modo de solucionar um problema)… E é claro que eu vou escrevendo sobre esses conceitos na medida em que eu for estudando.
Gabriel Rubens