Enumerados Avanzados

Introducción

Ya hemos visto y usado los tipos enumerados en la primera evaluación. Son apropiados para datos que tienen un rango de valores específicos:

enum Size { 
   SMALL, MEDIUM, LARGE, EXTRALARGE 
}

Esos rangos de valores son como constantes (por convenio se escriben con mayúsculas) que podemos asignar:

Size tamaño = Size.SMALL

Y son muy comodos de usar con switch:

enum Size {
 SMALL, MEDIUM, LARGE, EXTRALARGE
}

class Test {
 Size pizzaSize;
 public Test(Size pizzaSize) {
   this.pizzaSize = pizzaSize;
 }
 public void orderPizza() {
   switch(pizzaSize) {
     case SMALL:
       System.out.println("I ordered a small size pizza.");
       break;
     case MEDIUM:
       System.out.println("I ordered a medium size pizza.");
       break;
     default:
       System.out.println("I don't know which one to order.");
       break;
   }
 }
}

class Main {
 public static void main(String[] args) {
   Test t1 = new Test(Size.MEDIUM);
   t1.orderPizza();
 }
}

Métodos

Dentro de enumerados podemos crear métodos, para luego usarlos:

enum Size{
  SMALL, MEDIUM, LARGE, EXTRALARGE;

  public String getSize() {

    // this apunta en tiempo de ejecución en el main a SMALL
    switch(this) {
      case SMALL:
        return "small";

      case MEDIUM:
        return "medium";

      case LARGE:
        return "large";

      case EXTRALARGE:
        return "extra large";

      default:
        return null;
      }
   }
}
public static void main(String[] args) {
    System.out.println("The size of the pizza is " + Size.SMALL.getSize());
  }

Métodos predefinidos de Enum

  • ordinal(CONSTANTE): nos devuelve la posición dentro del enumerado.
  • compareTo(ENUM.CONSTANTE): comparación basada en ordinal(). Resultado como un compareTo normal.
  • toString(), name(), valueOf(): ya os imagináis lo que devuelven.
  • values(): nos devuelve un array con las constantes: Size[] enumArray = Size.values();

Constructores y atributos

En Java podemos tener constructores dentro de enumerados, como si fuera una clase normal. Y la diferencia que al definir las constantes podemos asignar valores. Y atributos:

enum Size {
   // enum constants calling the enum constructors 
   SMALL("The size is small."),
   MEDIUM("The size is medium."),
   LARGE("The size is large."),
   EXTRALARGE("The size is extra large.");

   private final String pizzaSize;

   // private enum constructor
   private Size(String pizzaSize) {
      this.pizzaSize = pizzaSize;
   }

   public String getSize() {
      return pizzaSize;
   }
}

class Main {
   public static void main(String[] args) {
      Size size = Size.SMALL;
      System.out.println(size.getSize());
   }
}

Otro ejemplo, con constructor, atributo y un método:

enum Direction {
  EAST(0), WEST(180), NORTH(90), SOUTH(270);

  // constructor
  private Direction(final int angle) {
    this.angle = angle;
  }

  // internal state
  private int angle;

  public int getAngle() {
    return angle;
  }
}

Incluso pueden soportar interfaces y algún aspecto más…

Ejercicio 1

Crea una interfaz con algún método, y a continuación que un enumerado la implemente. Prueba a ejecutar dicho método.

Ejercicio 2

Crea un interfaz que tengo un método llamado dia(), el enumerado tendrá de valores los días de la semana. Y el método los devolverá el día en numérico de la semana (Martes -> 2).