Java com café: Enums - Java

Enums - Java

Enums são um tipo de classe Java que quase nunca utilizamos. Acredito que muita gente nem imagina que esse tipo de classe existe. Diferente de classes comuns e interfaces, o Enum foi inserido na versão 5 do Java. Ele permitie enumerar uma quantidade de valores pré-definidos que podem ser aceitos para uma variável.
Vamos a um exemplo prático. Precisamos de uma variável que só aceite 3 valores: maçã, pera e uva. Então declaramos:
enum Frutas { MAÇÃ, PERA, UVA }; //É opcional colocar ponto-e-vírgula
Obs.: Por convenção as constantes são escritas em maiúsculas. Um Enum é constituido basicamente por suas constantes, mas logo veremos que podem existir outras coisas a mais. Eles podem ser declarados como membro de uma classe ou fora da classe, mas nunca dentro de métodos (inclusive o main). Outro ponto importante é que os Enums só aceitam os modificadores default e public (não aceita private, protected, final, abstract nem static). Veja um exemplo de declaração fora da classe:
enum Frutas { MAÇÃ, PERA, UVA }

public class Run {

 Frutas tipo; //Run tem uma variável de instância do tipo Frutas

 public static void main(String[] args) {
 
     Run r = new Run();
     r.tipo = Frutas.MAÇÃ;
 
 }
}
Enums não são do tipo String ou de outro tipo. Eles são do seu próprio tipo, neste caso Frutas. MAÇÃ, PERA ou UVA são tipos de Frutas. Se fizermos o teste:
if (Frutas.MAÇÃ instanceof Frutas)
 System.out.println("Maçã é do tipo Fruta");
O resultado será: Maçã é do tipo Fruta
Então sabemos o que são Enums, como e onde declará-los. E também sabemos que por ser uma classe, tem seu próprio tipo. Agora vamos ver umas coisas mais interessantes.
Construtores, Métodos e Variáveis em um Enum
Como os Enums são um tipo especial de classe, eles podem ter construtores, variáveis e até um corpo de classe para as constantes (mais adiante explico o que é essa coisa bizarra). Vamos ver como funcionam esses membros passando um parâmetro para cada constante:
 MAÇÃ("vermelha"), PERA("verde"), UVA("roxa");
Cada tipo de fruta agora recebe um parâmetro do tipo String, como numa chamada de método normal (poderíamos ter outros tipos, dependendo do construtor). De acordo com os argumentos, neste caso teríamos o seguinte construtor:
 Frutas(String cor){
     this.Cor = cor;
 }
Sendo assim, devemos ter uma variável de instância para receber a cor:
 private String Cor;
E ainda um método para retornar a cor da fruta escolhida:
 void getCor(){
     System.out.println("A cor da fruta escolhida é " + Cor);
 }
O Enum completo ficaria assim:
enum Frutas {

 //Passando parâmetros a cada constante
 MAÇÃ("vermelha"), PERA("verde"), UVA("roxa");

 //Construtor
 Frutas(String cor){
     this.Cor = cor;
 }
 //Variavel de instância
 private String Cor;

 //Método que mostra a cor da fruta escolhida
 void getCor(){
     System.out.println("A fruta escolhida é " + Cor);
 }

}
Observe que quando temos mais membros além das constantes é obrigatório o ponto-e-vírgula após as constantes.
Agora modifique a classe Run para que fique parecida com esta:
public class Run {

 Frutas nome;

 public static void main(String[] args) {
 
     Run r = new Run();
     r.nome = Frutas.MAÇÃ;
     r.nome.getCor();
 }
}
A saída será: A fruta escolhida é vermelha
Sobre o construtor do Enum devemos saber que ele nunca poderá ser invocado diretamente. Ele só pode ser chamado pelo próprio Enum, ou melhor, por cada constante. Os construtores também podem ser sobrecarregados, como no exemplo:
 MAÇÃ("vermelha"), PERA("verde"), UVA("roxa", "verde");

 Frutas(String cor){
     this.Cor = cor;
 }
 //Construtor sobrecarregado
 Frutas(String cor, String cor2){
 }
Corpo de Classe específico da constante
Como eu mencionei anteriormente, os Enums podem possuir uma coisa estranha chamada corpo de classe específico da constante. Esse corpo é um bloco de código que podemos definir para cada constante. Usamos esse corpo para substituir um método definido dentro do Enum. Vamos ver na prática:
enum Frutas {

 MAÇÃ,
 PERA,
 UVA{
     //Corpo da constante UVA
     //Códigos legais aqui...
 };

 void getFoo(){
     System.out.println("Frutas são saudáveis.");
 }

}
Observe que se chamarmos por r.nome.getFoo(), independente de qual fruta tenha sido escolhida, sempre teremos a saída: Frutas são saudáveis. Porém agora vamos sobrescrever o método dentro do corpo da constante UVA:
enum Frutas {

 MAÇÃ,
 PERA,
 UVA{
     void getFoo(){
         System.out.println("BAD FRUIT!!!");
     }
 };

 void getFoo(){
     System.out.println("Frutas são saudáveis.");
 }

}
E então chamamos:
     r.nome = Frutas.UVA;
     r.nome.getFoo();
A saída será: BAD FRUIT!!!
Ok, mas pra que fazer isso? Imagine que todos os elementos do Enum tenham uma propriedade, um código por exemplo. Mas um determinado elemento não pode ter aquele código. Então usamos o corpo da constante para definir um comportamento especial pra ele. É realmente difícil imaginar uma aplicação para isso, mas apenas saiba como funciona que será o bastante para passar no exame! E por hoje é só.
Bons estudos!

Nenhum comentário:

Postar um comentário