Semana 9 - Clases Abstractas, Métodos Abstractos e Interfaces en Java (POO)
Contexto
Imagina que estás desarrollando un sistema para gestionar alimentos típicos de Medellín, como la bandeja paisa, el mondongo y el postre de arequipe. El sistema debe permitir describir los alimentos, prepararlos y clasificarlos según si son platos principales o postres. Usaremos clases abstractas, métodos abstractos e interfaces para modelar este sistema de forma clara y modular.
Este ejemplo proporciona indicaciones para que implementes el código, sin mostrar la solución completa. El objetivo es que comprendas cómo usar estos conceptos de POO en un escenario simple y práctico.
Requisitos del Sistema
-
Clase Abstracta
Alimento:- Representa un alimento genérico con atributos comunes como
nombre(String) yprecio(double). - Debe incluir un método concreto para mostrar la información del alimento (por ejemplo,
mostrarInformacion()). - Debe incluir un método abstracto
preparar()que cada tipo de alimento implementará de forma específica.
- Representa un alimento genérico con atributos comunes como
-
Interfaz
Clasificable:- Define un método para clasificar el alimento, por ejemplo,
clasificar(), que indica si es un plato principal o un postre.
- Define un método para clasificar el alimento, por ejemplo,
-
Clases Concretas:
BandejaPaisa: Un plato principal que extiendeAlimentoe implementaClasificable.Mondongo: Otro plato principal que extiendeAlimentoe implementaClasificable.Arequipe: Un postre que solo implementaClasificable(no extiendeAlimento, para mostrar que las interfaces pueden usarse sin herencia).
-
Clase Principal:
- Debe demostrar el uso de polimorfismo creando instancias de los alimentos y llamando a sus métodos a través de referencias de tipo
AlimentoyClasificable.
- Debe demostrar el uso de polimorfismo creando instancias de los alimentos y llamando a sus métodos a través de referencias de tipo
Indicaciones para la Implementación
1. Crear la Clase Abstracta Alimento
- Declara la clase con la palabra clave
abstract. - Define dos atributos:
nombre(String) yprecio(double). - Crea un constructor que inicialice estos atributos.
- Implementa un método concreto
mostrarInformacion()que imprima el nombre y precio del alimento. - Declara un método abstracto
preparar()sin implementación (termina con;).
Indicación:
abstract class Alimento {
// Atributos
// Constructor
// Método concreto: mostrarInformacion()
// Método abstracto: preparar()
}
2. Crear la Interfaz Clasificable
- Declara una interfaz con la palabra clave
interface. - Define un método abstracto
clasificar()que no tenga implementación. - Opcionalmente, añade un método
defaultllamadoanunciar()que imprima un mensaje genérico como "¡Disfruta de la comida paisa!".
Indicación:
interface Clasificable {
// Método abstracto: clasificar()
// Método default: anunciar() (opcional)
}
3. Crear la Clase BandejaPaisa
- Extiende la clase
Alimentousandoextends. - Implementa la interfaz
Clasificableusandoimplements. - Crea un constructor que pase los parámetros
nombreyprecioal constructor deAlimento. - Implementa el método
preparar()para describir cómo se prepara una bandeja paisa (por ejemplo, "Preparando bandeja paisa con chicharrón, frijoles y arroz"). - Implementa el método
clasificar()para indicar que es un plato principal.
Indicación:
class BandejaPaisa extends Alimento implements Clasificable {
// Constructor
// Implementar preparar()
// Implementar clasificar()
}
4. Crear la Clase Mondongo
- Similar a
BandejaPaisa, extiendeAlimentoe implementaClasificable. - En
preparar(), describe la preparación del mondongo (por ejemplo, "Cocinando mondongo con callos y verduras"). - En
clasificar(), indica que es un plato principal.
Indicación:
class Mondongo extends Alimento implements Clasificable {
// Constructor
// Implementar preparar()
// Implementar clasificar()
}
5. Crear la Clase Arequipe
- Solo implementa
Clasificable(no extiendeAlimentopara mostrar la flexibilidad de las interfaces). - Define un atributo propio, como
tipo(String, por ejemplo, "postre de leche"). - Implementa
clasificar()para indicar que es un postre.
Indicación:
class Arequipe implements Clasificable {
// Atributo tipo
// Constructor
// Implementar clasificar()
}
6. Crear la Clase Principal
- Crea una clase
Maincon un métodomain. - Instancia un objeto de
BandejaPaisa, uno deMondongoy uno deArequipe. - Usa un arreglo de tipo
Alimentopara almacenarBandejaPaisayMondongo, y llama amostrarInformacion()ypreparar()para demostrar polimorfismo. - Usa un arreglo de tipo
Clasificablepara almacenar los tres objetos y llama aclasificar()(yanunciar()si usaste un métododefault). - Opcionalmente, usa
instanceofy casting para acceder a un método específico deBandejaPaisa.
Indicación:
public class Main {
public static void main(String[] args) {
// Crear instancias
// Arreglo de Alimento para polimorfismo
// Arreglo de Clasificable para polimorfismo
// Opcional: usar instanceof y casting
}
}
Objetivos Educativos
- Clase Abstracta: Entender cómo
Alimentoproporciona una base común con atributos y métodos compartidos, y cómopreparar()fuerza a las clases hijas a definir su propia lógica. - Interfaz: Comprender que
Clasificablepermite que clases no relacionadas (comoArequipe) compartan un comportamiento común. - Polimorfismo: Ver cómo se pueden usar referencias de tipo
AlimentoyClasificablepara tratar objetos de manera uniforme. - Métodos Abstractos: Reconocer que
preparar()yclasificar()obligan a las clases concretas a proporcionar implementaciones específicas. - Método
default(opcional): Explorar cómo una interfaz puede incluir lógica compartida.
Solución
// Interfaz Clasificable: Define un comportamiento para clasificar alimentos
interface Clasificable {
// Método abstracto para clasificar el alimento
void clasificar();
// Método default para anunciar el alimento
default void anunciar() {
System.out.println("¡Disfruta de la comida paisa!");
}
}
// Clase abstracta Alimento: Base para los alimentos típicos
abstract class Alimento {
protected String nombre;
protected double precio;
// Constructor
public Alimento(String nombre, double precio) {
this.nombre = nombre;
this.precio = precio;
}
// Método concreto para mostrar información
public void mostrarInformacion() {
System.out.println("Alimento: " + nombre + ", Precio: $" + precio);
}
// Método abstracto para preparar el alimento
public abstract void preparar();
}
// Clase BandejaPaisa: Extiende Alimento e implementa Clasificable
class BandejaPaisa extends Alimento implements Clasificable {
public BandejaPaisa(String nombre, double precio) {
super(nombre, precio);
}
@Override
public void preparar() {
System.out.println("Preparando " + nombre + " con chicharrón, frijoles, arroz y aguacate.");
}
@Override
public void clasificar() {
System.out.println(nombre + " es un plato principal.");
}
}
// Clase Mondongo: Extiende Alimento e implementa Clasificable
class Mondongo extends Alimento implements Clasificable {
public Mondongo(String nombre, double precio) {
super(nombre, precio);
}
@Override
public void preparar() {
System.out.println("Cocinando " + nombre + " con callos, verduras y especias.");
}
@Override
public void clasificar() {
System.out.println(nombre + " es un plato principal.");
}
}
// Clase Arequipe: Solo implementa Clasificable
class Arequipe implements Clasificable {
private String tipo;
public Arequipe(String tipo) {
this.tipo = tipo;
}
@Override
public void clasificar() {
System.out.println("Arequipe (" + tipo + ") es un postre.");
}
}
// Clase principal para demostrar el uso
public class Main {
public static void main(String[] args) {
// Crear instancias de los alimentos
Alimento bandeja = new BandejaPaisa("Bandeja Paisa", 35000.0);
Alimento mondongo = new Mondongo("Mondongo Antioqueño", 25000.0);
Clasificable arequipe = new Arequipe("postre de leche");
// Demostrar polimorfismo con clase abstracta Alimento
System.out.println("=== Información y Preparación de Alimentos ===");
Alimento[] alimentos = {bandeja, mondongo};
for (Alimento alimento : alimentos) {
alimento.mostrarInformacion();
alimento.preparar();
}
// Demostrar polimorfismo con interfaz Clasificable
System.out.println("\n=== Clasificación de Alimentos ===");
Clasificable[] clasificables = {(Clasificable) bandeja, (Clasificable) mondongo, arequipe};
for (Clasificable clasificable : clasificables) {
clasificable.anunciar();
clasificable.clasificar();
}
}
}