1. Clase base común

Hoy disfrutaremos de una mezcla heterogénea de temas interesantes. ¿Recuerdas cuando introdujimos la ChessItemclase base para simplificar todas las clases que representan piezas de ajedrez? Eso espero 🙂

Ahora imagine que cada pieza tiene un draw()método que maneja dibujarla en la pantalla. Llamas al draw()método y la pieza se dibuja a sí misma en sus coordenadas actuales. Sería conveniente trasladar este método a la clase base.

Si el draw()método estuviera en la clase base ChessItem, entonces podríamos anularlo en las clases de piezas y escribir un código elegante como este:

class ChessBoard
{
   public void drawAllChessItems()
   {
      // Add the pieces to the list
      ArrayList<ChessItem> items = new ArrayList<ChessItem>();
      items.add(new King());
      items.add(new Queen());
      items.add(new Bishop());

      // Draw them regardless of their type
      for(ChessItem item: items)
      {
         item.draw();
      }
   }
}

Al introducir la ChessItemclase base, pudimos simplificar mucho el código: no es necesario llamar a los métodos de cada clase por separado, podemos almacenar fácilmente todos los objetos en una sola colección, etc.

Pero aquí hay una pregunta interesante: ¿qué debe dibujar en la pantalla el draw()método declarado directamente en la ChessItemclase? Después de todo, no existe tal pieza en el ajedrez, por lo que no hay nada que dibujar.

Eso es exactamente correcto. Además, no tiene sentido crear ChessItemobjetos directamente. No es una pieza de ajedrez, sino más bien una abstracción , una clase que creamos para nuestra conveniencia. Así es como funciona la abstracción en OOP : movemos datos y métodos importantes (los que comparten todas las piezas) a una clase base y mantenemos sus diferencias en clases descendientes separadas.


2. Clases abstractas

Clases abstractas

Para tales situaciones, Java tiene un tipo especial de clase: la clase abstracta . Están diseñados para facilitar a los programadores el trabajo con clases similares y reducir la cantidad de código duplicado en ellas.

Aquí hay tres cosas que debe saber sobre las clases abstractas.

Método sin implementación

Una clase abstracta puede tener una declaración de método sin implementación. Esto es exactamente lo que hace que el método sea abstracto. El cuerpo del método simplemente se reemplaza con un punto y coma. Y antes del nombre del método, escribimos la abstractpalabra clave. Ejemplo:

public abstract class ChessItem
{
   public int x, y; // Coordinates
   private int value; // The piece's value
   public int getValue() // Ordinary method that returns value field
   {
      return value;
   }

   public abstract void draw(); // Abstract method. The implementation is missing.
}

Clase abstracta

Cada método sin implementación está marcado con la palabra clave abstract. Si una clase tiene incluso un método abstracto, la clase también se marca con la abstractpalabra clave.

Prohibir la creación de objetos.

No puede crear objetos de una clase abstracta . Dicho código simplemente no se compilará.

Código Descripción
ChessItem item = new ChessItem();
item.draw();
Este código no compila :
ChessItem item = new Queen();
item.draw();
pero puedes hacer esto

Heredar una clase abstracta

Si su clase hereda una clase abstracta, entonces necesita anular todos los métodos abstractos heredados, es decir, necesita escribir una implementación para ellos. De lo contrario, su propia clase también deberá declararse abstracta.

Si una clase tiene incluso un método no implementado declarado directamente en ella o heredado de una clase principal, entonces la clase se considera abstracta.

¿Y por qué es todo esto necesario? ¿Por qué se necesitan clases abstractas? ¿No es posible usar los ordinarios en su lugar? Y en lugar de métodos abstractos, ¿no podríamos simplemente escribir dos corchetes vacíos como el cuerpo del método?

Pudimos. Pero estas restricciones son similares al privatemodificador. Usamos la palabra clave private para evitar deliberadamente que otros programadores accedan directamente a los datos y forzarlos a usar solo nuestros métodos públicos al escribir sus clases.

Es lo mismo con las clases abstractas. El autor de una clase abstracta no quiere que se creen objetos de la clase. En cambio, el autor espera que los métodos abstractos se hereden de la clase abstracta y luego se anulen.

La ventaja de este enfoque es evidente en proyectos grandes. Cuantas más clases tenga, más claramente necesitará delinear sus roles. Verá el beneficio de este enfoque en un futuro próximo. Todo pasa por esto.