Autor Tema: Java qué significa la herencia, que un tipo sea especialización de otro CU00692B  (Leído 3488 veces)

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas tardes.

Os dejo una posible solución del ejercicio CU00692B del curso Java desde cero.

Citar
EJERCICIO

Considera que estás desarrollando un programa Java donde trabajas con la superclase Profesor y la subclase ProfesorEmerito. Crea el código para estas clases que cumpla los requisitos que indicamos.

Como atributos de la superclase tendremos nombre (String), edad (int) y añosConsolidados (int). Un método de la superclase será double obtenerSalarioBase () que obtendrá el salario base como (725 + el número de años consolidados multiplicado por 33.25).

En la subclase se trabajará con el campo adicional añosEmerito. Queremos hacer lo siguiente: sobreescribir el método obtenerSalarioBase () en la subclase para calcular el salario base del profesor emérito invocando mediante la palabra clave super al cálculo del salario base de Profesor y añadiéndole la cantidad de (47.80 * añosEmerito).

Código de la clase "Profesor":

Código: [Seleccionar]
public class Profesor{
    private String nombre;
    private int edad;
    private int anyosConsolidados;
   
    public Profesor(String nombre, int edad, int anyosConsolidados){
        this.nombre = nombre;
        this.edad = edad;
        this.anyosConsolidados = anyosConsolidados;
    }
   
    public Profesor(){
        nombre = "";
        edad = 0;
        anyosConsolidados = 0;
    }
   
    public void setNombre(String nombre){
        this.nombre = nombre;
    }
   
    public void setEdad(int edad){
        this.edad = edad;
    }
   
    public void setAnyosConsolidados(int anyosConsolidados){
        this.anyosConsolidados = anyosConsolidados;
    }
   
    public String getNombre(){return nombre;}
    public int getEdad(){return edad;}
    public int getAnyosConsolidados(){return anyosConsolidados;}
   
    public double obtenerSalarioBase(){
        double salarioBase;
        salarioBase = 725+(anyosConsolidados*33.25);
        return salarioBase;
    }
   
    public void mostrarInfoProfesor(){
        System.out.println("El profesor: "+getNombre()+" de: "+getEdad()+" años tiene: "+getAnyosConsolidados()+" y años consolidados y no tiene años de emérito.\nPor lo tanto le corresponde un salario de: "+obtenerSalarioBase()+" euros.");
    }
   
}

Código de la clase "ProfesorEmerito":

Código: [Seleccionar]
public class ProfesorEmerito extends Profesor{
    private int anyosEmerito;
   
    public ProfesorEmerito(String nombre, int edad, int anyosConsolidados, int anyosEmerito){
        super(nombre, edad, anyosConsolidados);
        this.anyosEmerito = anyosEmerito;
    }
   
    public ProfesorEmerito(){
        super();
        anyosEmerito = 0;
    }
   
    public void setAnyosEmerito(int anyosEmerito){
        this.anyosEmerito = anyosEmerito;
    }
   
    public int getAnyosEmerito(){return anyosEmerito;}
   
    public double obtenerSalarioBase(){
        double salarioBase;
        salarioBase = super.obtenerSalarioBase()+(47.80*anyosEmerito);
        return salarioBase;
    }
   
    public void mostrarInfoProfesor(){
        System.out.println("El profesor: "+getNombre()+" de: "+getEdad()+" años tiene: "+getAnyosConsolidados()+" años consolidados y "+getAnyosEmerito()+" años de emérito.\nPor lo tanto le corresponde un salario de: "+obtenerSalarioBase()+" euros.");
    }
}

Código de la clase "TestPalabraClaveSuper":

Código: [Seleccionar]
import java.util.ArrayList;

public class TestPalabraClaveSuper{
    public static void main(String []Args){
       
        //Creamos dos objetos de tipo "Profesor" y de tipo "ProfesorEmerito"
        Profesor profesor = new Profesor("José",65,45);
        ProfesorEmerito profesorEmerito = new ProfesorEmerito("Juan",65,45,5);
       
        //Creamos una lista de los objetos(profesores) creados.
        ArrayList<Profesor> listadoProfesores = new ArrayList<Profesor>();
        listadoProfesores.add(profesor);
        listadoProfesores.add(profesorEmerito);
       
        /*Invocamos sus métodos "mostrarInfoProfesor()".
        Como el objeot "ProfesorEmerito" también dispone de dicho método se ejecuta éste. En caso contrario se ejecutaría de su padre, es decir, del objeto "Profesor".
        Pero como también esté sobreescrito el método "obtenerSalarioBase()" el salario base del ojbeto "profesorEmerito" no varia.
        Podéis hacer la prueba eleminando de la clase "ProfesorEmerito" el método "mostrarInfoProfesor()".*/
        for(Profesor tmp: listadoProfesores){
            tmp.mostrarInfoProfesor();
        }
    }
}

Gracias.
« Última modificación: 18 de Marzo 2016, 08:55 por Mario R. Rancel »

Mario R. Rancel

  • Administrador
  • Experto
  • ********
  • APR2.COM
  • Mensajes: 1978
    • Ver Perfil
Buenos días el ejercicio está correcto

Una sugerencia para mejorar: en la clase Profesor has escrito esto

Código: [Seleccionar]
    public void mostrarInfoProfesor(){
        System.out.println("El profesor: "+getNombre()+" de: "+getEdad()+" años tiene: "+getAnyosConsolidados()+" y años consolidados y no tiene años de emérito.\nPor lo tanto le corresponde un salario de: "+obtenerSalarioBase()+" euros.");
    }


Error de concepto: estás considerando que Profesor es una cosa y que ProfesorEmerito es otra cosa.

Pero realmente no es así, decimos que ProfesorEmerito es un tipo de Profesor (a veces se dice que es una especialización de Profesor). Por ello un Profesor es algo "más general" que un ProfesorEmerito, algo que lo engloba. Un Profesor podría ser un ProfesorEmerito, o un ProfesorAyudante, o un ProfesorBecario... por tanto no es correcto decir que un Profesor no tiene años de emérito. Si es un ProfesorEmérito sí los tendrá.

El planteamiento correcto en programación orientada a objetos es que la superclase maneje e informe sobre sus atributos. La subclase reutilizará dicha información, y posiblemente añadirá alguna más.

En este ejercicio esto se traduciría en que los métodos quedarían así:

en la clase Profesor

Código: [Seleccionar]
    public void mostrarInfoProfesor(){
        System.out.println("El profesor: "+getNombre()+" de: "+getEdad()+" años tiene: "+getAnyosConsolidados()+" años consolidados y le corresponde un salario de: "+obtenerSalarioBase()+" euros.");
    }

En la clase ProfesorEmerito

Código: [Seleccionar]
    public void mostrarInfoProfesor(){
        super.mostrarInfoProfesor();
        System.out.print("Años de emérito "+getAnyosEmerito());
    }


Si entiendes bien esto habrás dado un buen paso

Las ideas interesantes son:

Profesor y ProfesorEmerito no son cosas distintas, uno es una "extensión de otro". Un ProfesorEmerito es también un Profesor. Un Profesor no sabemos si es ProfesorEmerito, quizás lo sea, pero no lo sabemos.

Una subclase hereda atributos y métodos de su superclase, por tanto reutiliza el código de la superclase, evitando repetir algo que ya esté en la superclase. En la subclase únicamente añadimos, no repetimos.

Saludos.

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas tardes, Mario.

Tienes razón. En mi cabeza tenía entendido que "Profesor" no es lo mismo que "ProfesorEmerito", pero no es así. Es decir, todas las subclases engloban en sí sus superclases, o sea que, "ProfesorEmerito" es un profesor emerito y también es un profesor a la vez.

Y también entiendo sobre lo que me explicas de no repetir información. Si una vez hemos hecho un método toString() en la superclase, en la subclase sólo tenemos que añadir los campos de esa misma clase.

Sí, requiere tiempo y compensión todo el tema de los objetos y su lógica, pero espero con poco a poco se me aclaren las cosas.

Un saludo.

PD: Voy a corregir el código de acuerdo con tus indicaciones, pero no voy a subir el código corregido porque creo que ha quedado aclarado el tema.

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".