1. Clase base común
Hoy disfrutaremos de una mezcla heterogénea de temas interesantes. ¿Recuerdas cuando introdujimos la ChessItem
clase 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 ChessItem
clase 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 ChessItem
clase? 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 ChessItem
objetos 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
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 abstract
palabra 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 abstract
palabra 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 |
---|---|
|
Este código no compila : |
|
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 private
modificador. 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.
GO TO FULL VERSION