Fundamentos java

Clases


Una clase en Java es una plantilla para crear objetos. Define atributos (variables) y métodos (funciones) que los objetos creados a partir de la clase pueden tener.

public class Animal {
    // Atributos
    private String nombre;
    private int edad;

    // Constructor
    public Animal(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
    }

    // Métodos
    public void hacerSonido() {
        System.out.println(«El animal hace un sonido»);
    }

    // Getters y Setters
    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }
}

Interfaces


Una interfaz en Java es un contrato que una clase puede implementar. Define métodos que la clase debe implementar, pero no proporciona la implementación de esos métodos.

public interface Volador {
    void volar();
}

public class Pajaro implements Volador {
    @Override
    public void volar() {
        System.out.println(«El pájaro está volando»);
    }
}

La anotación @Override en Java se utiliza para indicar que un método en una subclase está sobrescribiendo un método en su superclase. Esta anotación es opcional, pero es altamente recomendada porque ayuda a prevenir errores y mejora la legibilidad del código.

¿Qué hace @Override?


Verificación del Compilador: El compilador verifica que el método realmente sobrescriba un método en la superclase. Si no es así, se produce un error de compilación.


Claridad: Indica claramente que el método está destinado a sobrescribir un método de la superclase, lo que mejora la legibilidad y el mantenimiento del código.

Las interfaces son especialmente útiles en varias situaciones en Java:

1. Polimorfismo


Permiten que diferentes clases implementen la misma interfaz, lo que facilita el uso de polimorfismo. Esto significa que puedes tratar objetos de diferentes clases de la misma manera si implementan la misma interfaz.

public interface Volador {
    void volar();
}

public class Pajaro implements Volador {
    @Override
    public void volar() {
        System.out.println(«El pájaro está volando»);
    }
}

public class Avion implements Volador {
    @Override
    public void volar() {
        System.out.println(«El avión está volando»);
    }
}

public class Main {
    public static void main(String[] args) {
        Volador[] voladores = {new Pajaro(), new Avion()};
        for (Volador v : voladores) {
            v.volar();
        }
    }
}

2. Desacoplamiento


Ayudan a desacoplar el código, permitiendo que las clases dependan de abstracciones en lugar de implementaciones concretas. Esto hace que el código sea más flexible y fácil de mantener.

3. Múltiples Herencias


Java no permite la herencia múltiple de clases, pero una clase puede implementar múltiples interfaces. Esto permite que una clase herede comportamientos de múltiples fuentes.

public interface Nadador {
    void nadar();
}

public class Pato implements Volador, Nadador {
    @Override
    public void volar() {
        System.out.println(«El pato está volando»);
    }

    @Override
    public void nadar() {
        System.out.println(«El pato está nadando»);
    }
}

4. Definición de Contratos


Las interfaces definen un contrato que las clases deben cumplir. Esto es útil en el diseño de APIs y frameworks, donde se espera que las clases proporcionen implementaciones específicas de métodos definidos en la interfaz.

5. Pruebas Unitarias


Facilitan las pruebas unitarias al permitir la creación de implementaciones simuladas (mock) de interfaces. Esto es útil para aislar la lógica de negocio durante las pruebas.

Herencia


La herencia permite que una clase (subclase) herede atributos y métodos de otra clase (superclase). Esto promueve la reutilización del código y la creación de jerarquías de clases.

public class Perro extends Animal {
    private String raza;

    public Perro(String nombre, int edad, String raza) {
        super(nombre, edad); // Llama al constructor de la superclase
        this.raza = raza;
    }

    @Override
    public void hacerSonido() {
        System.out.println(«El perro ladra»);
    }

    public String getRaza() {
        return raza;
    }

    public void setRaza(String raza) {
        this.raza = raza;
    }
}


En este ejemplo, Perro hereda de Animal y añade un nuevo atributo raza. Además, sobrescribe el método hacerSonido para proporcionar una implementación específica para los perros.

¿Qué hace super en un constructor?


El super se utiliza para llamar al constructor de la clase padre (superclase) desde la clase hija (subclase). Esto es necesario para inicializar correctamente los atributos heredados de la superclase.

¿Por qué es importante?


Inicialización Correcta: Asegura que los atributos de la superclase se inicialicen correctamente. Si no se llama al constructor de la superclase, los atributos heredados pueden no ser inicializados adecuadamente.
Reutilización de Código: Permite reutilizar el código del constructor de la superclase, evitando duplicación y facilitando el mantenimiento.
Consistencia: Mantiene la consistencia en la jerarquía de clases, asegurando que todas las partes del objeto se inicialicen de manera coherente.


¿Qué pasa si no se pone super?


Llamada Implícita: Si no se pone super, Java inserta automáticamente una llamada al constructor sin argumentos de la superclase. Esto solo funciona si la superclase tiene un constructor sin argumentos.


Error de Compilación: Si la superclase no tiene un constructor sin argumentos y no se llama explícitamente a super, el código no compilará y se producirá un error.

public class Animal {
    private String nombre;

    public Animal(String nombre) {
        this.nombre = nombre;
    }
}

public class Perro extends Animal {
    private String raza;

    public Perro(String nombre, String raza) {
        // Error de compilación: no se llama al constructor de la superclase
        this.raza = raza;
    }
}

En este caso, como Animal no tiene un constructor sin argumentos, es obligatorio llamar a super(nombre) en el constructor de Perro.

Abstracciones

Programación Orientada a Objetos (POO) En POO, la abstracción permite crear clases que representan entidades del mundo real con atributos y métodos relevantes, mientras se ocultan los detalles de implementación. Ejemplo:

public abstract class Vehiculo {
    private String marca;
    private String modelo;

    public Vehiculo(String marca, String modelo) {
        this.marca = marca;
        this.modelo = modelo;
    }

    public abstract void conducir();
}

public class Coche extends Vehiculo {
    public Coche(String marca, String modelo) {
        super(marca, modelo);
    }

    @Override
    public void conducir() {
        System.out.println(«El coche está siendo conducido»);
    }
}

¿Te ha resultado útil??

0 / 0

Entradas relacionadas:
Deja una respuesta 0

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.