← Java EspañolChapter 09 of 13

Interfaces y Clases Abstractas

## Objetivos de Aprendizaje - Comprender las clases abstractas - Crear e implementar interfaces - Saber cuándo usar cada una - Dominar los métodos default y static de interfaces ## Clases Abstractas ### No Pueden Ser Instantiadas ```java public abstract class Shape { String color; public abstract double area(); // Método abstracto public void display() { // Método concreto System.out.println("Color: " + color); } } ``` ### Subclase Concreta ```java public class Circle extends Shape { double radius; public Circle(String color, double radius) { this.color = color; this.radius = radius; } @Override public double area() { return Math.PI * radius * radius; } } ``` ### Uso ```java // Shape s = new Shape(); // Error - no se puede instanciar Shape s = new Circle("Red", 5.0); System.out.println(s.area()); // 78.54... ``` ## Métodos Abstractos ### Sin Implementación ```java public abstract class Animal { public abstract void makeSound(); // Debe ser implementado } ``` ### Implementación Requerida ```java public class Dog extends Animal { @Override public void makeSound() { System.out.println("Woof!"); } } public class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow!"); } } ``` ## Interfaces ### Referencia: Contrato ```java public interface Drawable { void draw(); // Abstracto por defecto } ``` ### Implementación: Clases ```java public class Circle implements Drawable { @Override public void draw() { System.out.println("Drawing circle"); } } public class Rectangle implements Drawable { @Override public void draw() { System.out.println("Drawing rectangle"); } } ``` ### Uso de Interface ```java Drawable d = new Circle(); d.draw(); // Drawing circle d = new Rectangle(); d.draw(); // Drawing rectangle ``` ## Interface vs Clase Abstracta | Característica | Clase Abstracta | Interface | |----------------|-----------------|-----------| | Campos | Cualquier tipo | Solo constantes | | Métodos | Cualquiera | Default, static, abstract | | Constructores | Sí | No | | Herencia múltiple | No | Sí (múltiples interfaces) | | Modificadores de acceso | Cualquiera | public (implícito) | ## Métodos Default (Java 8+) ### Proporcionar Implementación ```java public interface Drawable { void draw(); default void print() { System.out.println("Printing..."); } } ``` ### Por qué Default? Compatibilidad hacia atrás: ```java public interface Drawable { void draw(); // Nuevo método con implementación por defecto default void print() { System.out.println("Default print"); } } // Las clases existentes no se rompen - heredan default ``` ## Métodos Estáticos en Interfaces ```java public interface MathUtil { static int add(int a, int b) { return a + b; } static double circleArea(double radius) { return Math.PI * radius * radius; } } // Se llama como: MathUtil.add(5, 3) ``` ## Múltiples Interfaces ### Clase Implementa Múltiples ```java public interface Printable { void print(); } public interface Drawable { void draw(); } public class Document implements Printable, Drawable { @Override public void print() { System.out.println("Printing document"); } @Override public void draw() { System.out.println("Drawing document"); } } ``` ### Interface Extiende Interface ```java public interface Readable extends Printable { void read(); } // La clase que implemente Readable debe implementar // tanto read() (de Readable) como print() (de Printable) ``` ## Campos de Interface ### Siempre Constantes ```java public interface Constants { int MAX_SIZE = 100; // public static final String DEFAULT_NAME = "Unknown"; // public static final } // Uso int size = Constants.MAX_SIZE; ``` ## Interfaces Funcionales ### Método Abstracto Único ```java @FunctionalInterface public interface Comparator { int compare(T o1, T o2); // equals() ya está implementado (de Object) } ``` ### Expresiones Lambda ```java import java.util.Arrays; import java.util.Comparator; String[] names = {"Charlie", "Alice", "Bob"}; Arrays.sort(names, (a, b) -> a.compareTo(b)); // o Arrays.sort(names, Comparator.naturalOrder()); ``` ## Polimorfismo con Interfaces ```java public interface Shape { double area(); } public class Circle implements Shape { double radius; @Override public double area() { return Math.PI * radius * radius; } } public class Rectangle implements Shape { double width, height; @Override public double area() { return width * height; } } public static double totalArea(Shape[] shapes) { double total = 0; for (Shape s : shapes) { total += s.area(); } return total; } ``` ## Métodos Privados (Java 9+) ### Reutilización de Código en Interfaces ```java public interface DataProcessor { default void process(String data) { String cleaned = clean(data); validate(cleaned); save(cleaned); } private String clean(String data) { return data.trim().toLowerCase(); } private void validate(String data) { if (data.isEmpty()) { throw new IllegalArgumentException("Empty data"); } } private void save(String data) { // implementación de guardado } } ``` ## Resumen - Clases abstractas: implementación parcial, herencia simple - Interfaces: solo contrato (históricamente), herencia múltiple - `abstract class Shape` - usar cuando clases relacionadas comparten estado - `interface Drawable` - usar cuando clases no relacionadas comparten comportamiento - Los métodos default proporcionan compatibilidad hacia atrás - Las interfaces soportan herencia múltiple - Las interfaces funcionales pueden usar expresiones lambda

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →