Abstracción en Java Explicada: Simplifica Código y Mejora Legibilidad
Según el diccionario, abstracción es tratar con ideas en lugar de eventos. Ejemplo: al enviar un correo, los detalles complejos (protocolos, servidores) están ocultos; solo escribes el contenido, destinatario y pulsas enviar.
En programación orientada a objetos, la abstracción oculta los detalles de implementación y expone solo la funcionalidad. El usuario sabe qué hace el objeto, no cómo lo hace.
En Java, la abstracción se logra con clases abstractas e interfaces.
Clase Abstracta
Una clase declarada con abstract.
- Puede tener métodos abstractos (sin cuerpo) y métodos concretos.
- Si tiene al menos un método abstracto, debe declararse
abstract. - No se puede instanciar directamente.
- Para usarla, hay que heredarla e implementar sus métodos abstractos.
- Si heredas una clase abstracta, debes implementar todos sus métodos abstractos (o declarar tu clase también abstracta).
Ejemplo: Clase Abstracta Employee
public abstract class Employee {
private String name, address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Construyendo Employee");
this.name = name; this.address = address; this.number = number;
}
// Método concreto
public void mailCheck() {
System.out.println("Enviando cheque a " + name + " " + address);
}
// Método abstracto: sin cuerpo, solo firma
public abstract double computePay();
// getters/setters...
}
Intentar instanciar Employee causa error de compilación:
Employee e = new Employee("George", "Houston", 43);
// Error: Employee is abstract; cannot be instantiated
Herencia de Clase Abstracta
La subclase concreta implementa los métodos abstractos.
Ejemplo: Salary extiende Employee
public class Salary extends Employee {
private double salary;
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
this.salary = salary;
}
@Override
public double computePay() {
System.out.println("Calculando nómina para " + getName());
return salary / 52; // pago semanal
}
@Override
public void mailCheck() {
System.out.println("Dentro de mailCheck de Salary");
System.out.println("Enviando cheque a " + getName() + " con salario " + salary);
}
}
Uso Polimórfico
public class AbstractDemo {
public static void main(String[] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Llamada con referencia Salary --");
s.mailCheck();
System.out.println("\nLlamada con referencia Employee --");
e.mailCheck(); // invoca Salary.mailCheck() por polimorfismo
}
}
Salida:
Construyendo Employee Construyendo Employee Llamada con referencia Salary -- Dentro de mailCheck de Salary Enviando cheque a Mohd Mohtashim con salario 3600.0 Llamada con referencia Employee -- Dentro de mailCheck de Salary Enviando cheque a John Adams con salario 2400.0
Métodos Abstractos
Un método declarado abstract tiene firma pero no cuerpo (termina en ;).
public abstract class Employee {
public abstract double computePay(); // sin llaves, solo punto y coma
}
Consecuencias
- La clase que lo contiene debe ser abstracta.
- Cualquier subclase concreta debe implementarlo (o ser abstracta).
Nota: Eventualmente una clase concreta en la jerarquía debe implementar el método; de lo contrario, tendrás una cadena de clases abstractas que no se pueden instanciar.
Abstracción vs Encapsulamiento
| Abstracción | Encapsulamiento |
|---|---|
| Oculta cómo se hace (implementación) | Oculta qué datos (estado interno) |
| Nivel de diseño: "qué hace el objeto" | Nivel de implementación: "cómo se guardan los datos" |
| Lograda con clases abstractas / interfaces | Lograda con private + getters/setters |
Cuándo Usar Clase Abstracta vs Interfaz
- Clase abstracta: Cuando hay código compartido (campos, métodos concretos) entre subclases relacionadas; relación ES-UN fuerte.
- Interfaz: Cuando defines un contrato de comportamiento sin implementación compartida; una clase puede implementar múltiples interfaces.
Java
- Palabra clave final en Java: Variables, métodos y clases
- Operador instanceof en Java: Guía completa
- Clases y métodos abstractos en Java: Guía completa
- Entendiendo las clases anidadas estáticas en Java: Uso, diferencias y ejemplos
- Dominando las clases internas anónimas en Java: Definición, sintaxis y ejemplos prácticos
- Patrón Singleton en Java explicado: Cómo implementarlo y usarlo de forma segura
- Dominando la Reflexión en Java: Inspeccionando clases, métodos y campos en tiempo de ejecución
- Dominando ObjectOutputStream de Java: Serialización, Métodos y Ejemplos Prácticos
- Dominando Java Generics: Construyendo Código Reutilizable y Type-Safe
- Dominando las operaciones de archivos en Java con java.io: creación, lectura, escritura y eliminación
- Interfaz vs Clase Abstracta en Java: Cómo elegir la abstracción correcta