Antes de tudo, recomendo este artigo: Java: Quando criar uma classe final
Se o fizerem, quando o usarão para que eu possa entender melhor e saber quando usá-lo.
Uma final
classe é simplesmente uma classe que não pode ser estendida .
(Isso não significa que todas as referências a objetos da classe agiriam como se fossem declaradas como final
.)
Quando é útil declarar uma classe como final, é abordado nas respostas desta pergunta:
Se o Java é orientado a objetos e você declara uma classe final
, isso não impede a idéia de que a classe tenha as características dos objetos?
Em certo sentido, sim.
Ao marcar uma classe como final, você desativa um recurso poderoso e flexível do idioma para essa parte do código. Algumas classes, no entanto, não devem (e em certos casos não podem ) ser projetadas para levar em consideração a subclasse de uma maneira boa. Nesses casos, faz sentido marcar a turma como final, mesmo que isso limite o POO. (Lembre-se, no entanto, que uma classe final ainda pode estender outra classe não-final.)
Em Java, itens com o
final
modificador não podem ser alterados!Isso inclui classes finais, variáveis finais e métodos finais:
fonte
final
modificador não podem ser alterados!", É muito categórica e, de fato, não está totalmente correta. Como disse Grady Booch, "um objeto tem estado, comportamento e identidade". Embora não possamos alterar a identidade de um objeto depois que sua referência foi marcada como final, temos a chance de alterar seu estado atribuindo novos valores aos seus nãofinal
campos (desde que, é claro, eles os tenham). planejando para obter uma certificação do Oracle Java (como 1Z0-808, etc.) deve manter isso em mente, pois pode haver perguntas sobre este aspecto no exame ...Um cenário em que final é importante, quando você deseja impedir a herança de uma classe, por motivos de segurança. Isso permite que você garanta que o código que você está executando não possa ser substituído por alguém.
Outro cenário é para otimização: pareço lembrar que o compilador Java alinha algumas chamadas de função das classes finais. Portanto, se você chamar
a.x()
e a for declaradofinal
, sabemos em tempo de compilação qual será o código e poderá integrar a função de chamada. Não tenho ideia se isso é realmente feito, mas com final é uma possibilidade.fonte
O melhor exemplo é
que é uma classe imutável e não pode ser estendida. Claro, há mais do que apenas tornar a aula final imutável.
fonte
Leitura relevante: O Princípio Aberto-Fechado de Bob Martin.
Citação principal:
A
final
palavra-chave é o meio de aplicar isso em Java, seja usado em métodos ou em classes.fonte
final
torna a classe fechada para extensão em vez de aberta? Ou estou interpretando isso literalmente?final
uma declaração de classe / método não faria sentido se você quiser que o código de implementação seja fechado para modificação, mas aberto para extensão por herança.Se você imaginar a hierarquia de classes como uma árvore (como em Java), as classes abstratas podem ser apenas ramificações e as classes finais são aquelas que só podem ser folhas. As classes que se enquadram em nenhuma dessas categorias podem ser ramos e folhas.
Não há violação dos princípios de OO aqui, final é simplesmente fornecer uma simetria agradável.
Na prática, você deseja usar final se quiser que seus objetos sejam imutáveis ou se estiver escrevendo uma API, para sinalizar aos usuários da API que a classe simplesmente não se destina à extensão.
fonte
A palavra
final
- chave em si significa que algo é final e não deve ser modificado de forma alguma. Se uma classe estiver marcadafinal
, ela não poderá ser estendida ou subclassificada. Mas a questão é por que marcamos uma classefinal
? IMO existem várias razões:Ouvi dizer que a classe de marcação
final
melhora a eficiência, mas, francamente, não achei que esse argumento tivesse muito peso.Talvez sim, mas às vezes esse é o objetivo pretendido. Às vezes, fazemos isso para obter maiores benefícios de segurança etc., sacrificando a capacidade dessa classe de ser estendida. Mas uma aula final ainda pode estender uma aula, se necessário.
Em uma nota lateral, devemos preferir composição do que herança e a
final
palavra - chave realmente ajuda a aplicar esse princípio.fonte
Tenha cuidado ao fazer uma aula "final". Como se você quiser escrever um teste de unidade para uma classe final, não poderá subclassificar essa classe final para usar a técnica de quebra de dependência "Método de subclasse e substituição" descrita no livro de Michael C. Feathers "Trabalhando efetivamente com o código legado" . Neste livro, Feathers disse: "Sério, é fácil acreditar que selado e final é um erro errado, que nunca deveria ter sido adicionado a linguagens de programação. Mas a falha real está conosco. Quando dependemos diretamente de bibliotecas que estão fora de nosso controle, estamos apenas pedindo problemas ".
fonte
final class
pode evitar a quebra da API pública ao adicionar novos métodosSuponha que na versão 1 da sua
Base
classe você faça:e um cliente faz:
Então, se na versão 2 você deseja adicionar um
method
método paraBase
:isso quebraria o código do cliente.
Se tivéssemos usado
final class Base
, o cliente não seria capaz de herdar e a adição do método não quebraria a API.fonte
Se a classe estiver marcada
final
, significa que a estrutura da classe não pode ser modificada por nada externo. Onde isso é mais visível, quando você está fazendo uma herança polimórfica tradicional, basicamenteclass B extends A
simplesmente não funciona. É basicamente uma maneira de proteger algumas partes do seu código (até o ponto) .Para esclarecer, a marcação de classe
final
não marca seus camposfinal
e, como tal, não protege as propriedades do objeto, mas a estrutura de classe real.fonte
PARA ENCONTRAR O PROBLEMA DA CLASSE FINAL:
Existem duas maneiras de fazer uma aula final. O primeiro é usar a palavra-chave final na declaração de classe:
A segunda maneira de finalizar uma classe é declarar todos os seus construtores como privados:
Marcá-lo como final evita o problema se descobrir que é realmente um final, para demonstrar o olhar para esta classe de teste. parece público à primeira vista.
Infelizmente, como o único construtor da classe é privado, é impossível estender essa classe. No caso da classe Teste, não há razão para que a classe seja final. A classe Test é um bom exemplo de como as classes finais implícitas podem causar problemas.
Portanto, você deve marcá-lo como final quando implicitamente tornar uma classe final, tornando seu construtor privado.
fonte
Uma classe final é uma classe que não pode ser estendida. Os métodos também podem ser declarados como finais para indicar que não podem ser substituídos pelas subclasses.
Impedir que a classe seja subclassificada pode ser particularmente útil se você escrever APIs ou bibliotecas e quiser evitar ser estendido para alterar o comportamento base.
fonte
Uma vantagem de manter uma classe como final:
A classe String é mantida final para que ninguém possa substituir seus métodos e alterar a funcionalidade. por exemplo, ninguém pode alterar a funcionalidade do método length (). Ele sempre retornará o comprimento de uma string.
O desenvolvedor desta classe não queria que ninguém mudasse a funcionalidade dessa classe, então ele a manteve como final.
fonte
Sim, às vezes você pode querer isso, por motivos de segurança ou velocidade. É feito também em C ++. Pode não ser o aplicável aos programas, mas muito mais aos frameworks. http://www.glenmccl.com/perfj_025.htm
fonte
Em java, a palavra-chave final é usada para as ocasiões abaixo.
fonte
As aulas finais não podem ser estendidas. Portanto, se você deseja que uma classe se comporte de uma certa maneira e não substitua os métodos (com código possivelmente menos eficiente e mais malicioso), você pode declarar toda a classe como métodos finais ou específicos que você não deseja que sejam mudou.
Como declarar uma classe não impede que uma classe seja instanciada, isso não significa que impedirá a classe de ter as características de um objeto. É só que você terá que seguir os métodos da maneira como eles são declarados na classe.
fonte
pense em FINAL como o "fim da linha" - esse cara não pode mais produzir filhos. Portanto, quando você vê dessa maneira, existem vários cenários do mundo real que você encontrará, exigindo que você marque um marcador de 'fim de linha' para a classe. É um design orientado a domínio - se o seu domínio exigir que uma determinada ENTITY (classe) não possa criar subclasses, marque-a como FINAL.
Devo observar que não há nada que o impeça de herdar uma classe "deve ser marcada como final". Mas isso geralmente é classificado como "abuso de herança" e é feito porque na maioria das vezes você deseja herdar alguma função da classe base em sua classe.
A melhor abordagem é examinar o domínio e deixá-lo ditar suas decisões de design.
fonte
Como dito acima, se você quiser que ninguém possa alterar a funcionalidade do método, poderá declará-lo como final.
Exemplo: caminho do arquivo do servidor de aplicativos para download / upload, sequência de divisão baseada em deslocamento, métodos que você pode declarar como Final para que essas funções do método não sejam alteradas. E se você quiser esses métodos finais em uma classe separada, defina essa classe como Classe final. Portanto, a classe Final terá todos os métodos finais, onde o método Final pode ser declarado e definido na classe não final.
fonte
A classe Looper do Android é um bom exemplo prático disso. http://developer.android.com/reference/android/os/Looper.html
A classe Looper fornece determinadas funcionalidades que NÃO devem ser substituídas por nenhuma outra classe. Portanto, não há subclasse aqui.
fonte
Digamos que você tenha uma
Employee
classe que tenha um métodogreet
. Quando ogreet
método é chamado, ele simplesmente imprimeHello everyone!
. Então esse é o comportamento esperado dogreet
métodoAgora, deixe a
GrumpyEmployee
subclasseEmployee
e substitua ogreet
método, como mostrado abaixo.Agora, no código abaixo, dê uma olhada no
sayHello
método Ele toma aEmployee
instância como um parâmetro e chama o método greet, esperando que ele digaHello everyone!
Mas o que obtemos éGet lost!
. Essa mudança de comportamento se deve aEmployee grumpyEmployee = new GrumpyEmployee();
Esta situação pode ser evitada se a
Employee
aula foi feitafinal
. Imagine a quantidade de caos que um programador atrevido poderia causar seString
Classe não fosse declarada comofinal
.fonte
A aula final não pode ser estendida mais. Se não precisamos tornar uma classe herdável em java, podemos usar essa abordagem.
Se precisarmos fazer com que métodos específicos de uma classe não sejam substituídos, basta colocar a palavra-chave final na frente deles. Lá a classe ainda é herdável.
fonte
A Orientação a Objetos não é sobre herança, é sobre encapsulamento. E a herança quebra o encapsulamento.
Declarar uma aula final faz todo o sentido em muitos casos. Qualquer objeto que represente um "valor" como uma cor ou uma quantia em dinheiro pode ser definitivo. Eles estão por conta própria.
Se você estiver escrevendo bibliotecas, finalize suas aulas, a menos que você as indente explicitamente como derivadas. Caso contrário, as pessoas podem derivar suas classes e substituir métodos, quebrando suas suposições / invariantes. Isso também pode ter implicações de segurança.
Joshua Bloch em “Java Efetivo” recomenda projetar explicitamente para herança ou proibi-la e ele observa que projetar para herança não é tão fácil.
fonte