domingo, 11 de junio de 2017

20-Programación Orientada a Objetos en Java (parte X). Uso de super y sobrescritura de métodos

Ya hemos visto en tutoriales anteriores la herencia en Java y la sobrecarga de métodos y, ha llegado el momento de hablar de dos funciones que nos permitirán tener un mayor uso sobre la herencia, buscando siempre la reutilización de código. Vamos a ver en primer lugar la palabra reservada super para terminar finalmente con la sobrescritura de métodos.


Palabra reservada super.

La palabra super se utiliza para acceder a métodos y/o atributos de la clase padre. Ya vimos el uso de this que hacía referencia a atributos del mismo objeto del que hacía la llamada, pues super se utiliza para llamar a métodos o atributos de una superclase.
Se utiliza mucho en los métodos constructor, para llamar al método constructor de la superclase.
Veámoslo en un ejemplo en el que utilizaremos la clase padre Persona y la subclase Alumno.


public class Persona {
    
    //Atributos
    String nombre;
    String apellidos;
    int edad;
    String trabajo;
    
    //Método constructor que inicializa los atributos a los valores que le pasemos
    //como argumentos cuando creemos una instancia de esta clase.
    public Persona(String nombre, String apellidos, int edad, String trabajo){
        
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.trabajo = trabajo;
        
    }
    
    //Método constructor que se le pasa como parámetro un objeto de la clase 
    //Persona. Esto significa que este objeto tendrá los mismos valores en 
    //los atributos que el objeto pasado como argumento.
    public Persona(Persona b){
        this.nombre = b.nombre;
        this.apellidos = b.apellidos;
        this.edad = b.edad;
        this.trabajo = b.trabajo;
    }
    
    public void mostrarMensaje(){
        System.out.println("Esto es la clase Persona, que será superclase de la clase Alumno");
    }
    
}
public class Alumno extends Persona {
    
    //Atributos específicos de Alumno
    String curso;
    int notaMedia;
    String nombreColegio;
    
    //Creamos un método constructor en el que vamos a ver el funcionamiento
    //de super.
    
    public Alumno(String nombre, String apellidos, int edad, String trabajo,
            String curso, int notaMedia, String nombreColegio){
        //super siempre tiene que ir en primer lugar, antes que cualquier
        //sentencia. Llamamos al constructor de la superclase con super
        super(nombre, apellidos, edad, trabajo);
        
        this.curso = curso;
        this.notaMedia = notaMedia;
        this.nombreColegio = nombreColegio;
        
    }
    
    //Métodos propios de Alumno
    
    public void calcularNotaMedia(){
        //Definiríamos el método para calcular la nota media
    }
    
    public void cambiarColegio(String nuevoColegio){
        nombreColegio = nuevoColegio;
    }
}

Como podemos ver, en la clase Alumno creamos el constructor en el que utilizamos super para llamar al constructor de la clase Persona, que es la super clase de Alumno.

 Sobrescritura de Métdos.

Ya vimos en un tutorial anterior lo que era la sobrecarga de métodos, ahora vamos a ver otra función más que tiene el lenguaje de programación Java, la sobrescritura de métodos.
La sobrescritura de métodos también va ligado con el uso de la herencia. La sobrescritura de métodos es aquel método que es definido en una clase padre y, que en una de sus subclases se incorpora ese método, o métodos, pero de distinta forma que el método de la superclase, normalmente para cambiar la función o añadir funcionalidad al método.
Los métodos sobrescritos tienen el mismo nombre que el método original y antes del método se suele poner la etiqueta @Override para indicar que ese va a ser un método sobrescrito.
No es obligatorio poner esa etiqueta pero es de gran ayuda porque, como hemos dicho, un método sobrescrito tiene el mismo nombre que el método de la clase padre, por lo tanto si no indicamos esta etiqueta, si nos equicamos al escribir el método lo que estaremos haciendo realmente es crear un nuevo método, y no sobrescribirlo que es lo que realmente queremos.
Vamos a ver toda esta teoría co un ejemplo muy claro, siguiendo con las clases de Persona y Alumno.

public class Persona {
    
    //Atributos
    String nombre;
    String apellidos;
    int edad;
    String trabajo;
    
    //Método constructor que inicializa los atributos a los valores que le pasemos
    //como argumentos cuando creemos una instancia de esta clase.
    public Persona(String nombre, String apellidos, int edad, String trabajo){
        
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.trabajo = trabajo;
        
    }
    
    //Método constructor que se le pasa como parámetro un objeto de la clase 
    //Persona. Esto significa que este objeto tendrá los mismos valores en 
    //los atributos que el objeto pasado como argumento.
    public Persona(Persona b){
        this.nombre = b.nombre;
        this.apellidos = b.apellidos;
        this.edad = b.edad;
        this.trabajo = b.trabajo;
    }
    //Método mostrarNombre que será sobrescrito en la subclase
    public void mostrarNombre(){
        System.out.println("El nombre de la persona es: " + this.nombre);
    }
    
}

El código de la clase Persona es prácticamente el mismo, lo único que he creado un nuevo método llamado mostrarNombre que muestra el nombre de la persona. A continuación, en la clase Alumno vamos a sobrescribir este método para que muestre el mensaje un poco más personalizado. Por ejemplo no queremos que muestre "el nombre de la persona es...", sino que queremos que diga "El nombre del Alumno es..."

public class Alumno extends Persona {
    
    //Atributos específicos de Alumno
    String curso;
    int notaMedia;
    String nombreColegio;
    
    //Creamos un método constructor en el que vamos a ver el funcionamiento
    //de super.
    
    public Alumno(String nombre, String apellidos, int edad, String trabajo,
            String curso, int notaMedia, String nombreColegio){
        //super siempre tiene que ir en primer lugar, antes que cualquier
        //sentencia. Llamamos al constructor de la superclase con super
        super(nombre, apellidos, edad, trabajo);
        
        this.curso = curso;
        this.notaMedia = notaMedia;
        this.nombreColegio = nombreColegio;
        
    }
    
    //Métodos propios de Alumno
    
    public void calcularNotaMedia(){
        //Definiríamos el método para calcular la nota media
    }
    
    public void cambiarColegio(String nuevoColegio){
        nombreColegio = nuevoColegio;
    }

    public String getNombre() {
        return nombre;
    }
    
    
    @Override
    public void mostrarNombre(){
        System.out.println("El nombre del Alumno es: " + this.nombre);
    }
    
    
}

En la clase Alumno es el mismo código que en otros ejemplos con el único cambio de la sobrescritura del método mostrarNombre().

Utilizar super y la sobrescritura de métodos.

Bueno hemos visto el uso de la palabra super, que lo utilizábamos para acceder métodos, atributos de la superclase, pero sobre todo cuando queremos llamar al constructor de una superclase.
También hemos visto qué es y como utilizar la sobrescritura de métodos. Pues bien, ahora vamos a ver que a veces, en una superclase podemos crear un método que, más tarde, en una subclase queremos sobrescribir el método pero queriendo que haga la misma funcionalidad que el método de la superclase pero con alguna funcionalidad mas.
En palabras esto suena raro y poco útil, así que vamos a verlo con un ejemplo, utilizando las clases Persona y Alumno que hemos estado utilizando hasta ahora.

En primer lugar, en la clase Persona creamos un método mostrarDatos() que mostrará los datos de la persona, como su nombre, apellidos, edad y el trabajo que tiene.

public class Persona {
    
    //Atributos
    String nombre;
    String apellidos;
    int edad;
    String trabajo;
    
    //Método constructor que inicializa los atributos a los valores que le pasemos
    //como argumentos cuando creemos una instancia de esta clase.
    public Persona(String nombre, String apellidos, int edad, String trabajo){
        
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.trabajo = trabajo;
        
    }
    
    //Método constructor que se le pasa como parámetro un objeto de la clase 
    //Persona. Esto significa que este objeto tendrá los mismos valores en 
    //los atributos que el objeto pasado como argumento.
    public Persona(Persona b){
        this.nombre = b.nombre;
        this.apellidos = b.apellidos;
        this.edad = b.edad;
        this.trabajo = b.trabajo;
    }
    
    public void mostrarNombre(){
        System.out.println("El nombre de la persona es: " + this.nombre);
    }
    
    
    //Método que será utilizado en la subclase para sobrescribirlo
    //y utilizando la palabra super.
    public void mostrarDatos(){
        System.out.println("El nombre es: " + this.nombre);
        System.out.println("Los apellidos son: " + this.apellidos);
        System.out.println("La edad es: " + this.edad);
        System.out.println("Trabaja en: " + this.trabajo);
    }
    
}

Ahora, en la clase Alumno sobrescribiremos el método mostrarDatos() de la clase Persona para que también muestre los atributos del Alumno. Como también queremos que muestre los datos de la superclase, utilizaremos la palabra super para llamar al método de la superclase mostrarDatos y solo quedaría sobrescribir el método de la subclase para mostrar los datos de los Alumnos:

public class Alumno extends Persona {
    
    //Atributos específicos de Alumno
    String curso;
    int notaMedia;
    String nombreColegio;
    
    //Creamos un método constructor en el que vamos a ver el funcionamiento
    //de super.
    
    public Alumno(String nombre, String apellidos, int edad, String trabajo,
            String curso, int notaMedia, String nombreColegio){
        //super siempre tiene que ir en primer lugar, antes que cualquier
        //sentencia. Llamamos al constructor de la superclase con super
        super(nombre, apellidos, edad, trabajo);
        
        this.curso = curso;
        this.notaMedia = notaMedia;
        this.nombreColegio = nombreColegio;
        
    }
    
    //Métodos propios de Alumno
    
    public void calcularNotaMedia(){
        //Definiríamos el método para calcular la nota media
    }
    
    public void cambiarColegio(String nuevoColegio){
        nombreColegio = nuevoColegio;
    }

    public String getNombre() {
        return nombre;
    }
    
    
    @Override
    public void mostrarNombre(){
        System.out.println("El nombre del Alumno es: " + this.nombre);
    }
    
    
    @Override
    public void mostrarDatos(){
        super.mostrarDatos();//Llamamos al método de la superclase con super.
        //Ahora mostramos los datos del alumno
        System.out.println("Está cursando: " + this.curso);
        System.out.println("Tiene una nota media de: " + this.notaMedia);
        System.out.println("Va al colegio: " + this.nombreColegio);
    }
    
}

Si creamos un objeto alumno y ejecutamos su método mostrar datos, vemos como muestra por pantalla todos los datos:

Bueno y esto ha sido todo en este tutorial, es

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...