Autor Tema: Clases y métodos abstractos Java public abstract class código ejemplo CU00695B  (Leído 3739 veces)

Dimitar Stefanov

  • Experto
  • *****
  • Mensajes: 598
    • Ver Perfil
Buenas tardes. A continuación procedo a la exposición de una posible solución del ejercicio CU00695B del curso Java.

Citar
EJERCICIO

Declara una clase abstracta Legislador que herede de la clase Persona, con un atributo provinciaQueRepresenta (tipo String) y otros atributos. Declara un método abstracto getCamaraEnQueTrabaja. Crea dos clases concretas que hereden de Legislador: la clase Diputado y la clase Senador que sobreescriban los métodos abstractos necesarios. Crea una lista de legisladores y muestra por pantalla la cámara en que trabajan haciendo uso del polimorfismo.

El código de la clase "Persona":

Código: [Seleccionar]
public class Persona{
    private String nombre;
    private String apellidos;
    private int edad;

    public Persona(String nombre, String apellidos, int edad){
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
    }
   
    public Persona(){
   
    }
   
    public String getNombre(){return nombre;}
    public String getApellidos(){return apellidos;}
    public int getEdad(){return edad;}
   
    //Sobreescribimos el método toString()
    public String toString(){
        Integer datoEdad = edad;
        return "Nombre: "+nombre+" "+apellidos+". Edad: "+datoEdad.toString();
    }
}

El código de la clase "Legislador":

Código: [Seleccionar]
//Creamos una clase de tipo "abstract"
public abstract class Legislador extends Persona{
    private String provinciaQueRepresenta;
    private int anyosParlamento;
    protected String camara;
   
    public Legislador(String nombre, String apellidos, int edad, String provinciaQueRepresenta, int anyosParlamento, String camara){
        super(nombre, apellidos, edad);
        this.anyosParlamento = anyosParlamento;
        this.provinciaQueRepresenta = provinciaQueRepresenta;
        this.camara = camara;
    }
   
    public String getProvinciaQueRepresenta(){return provinciaQueRepresenta;}
    public int getAnyosParlamento(){return anyosParlamento;}
   
    //Creamos un método "abstract" el que no podremos invocar si no lo sobreescribamos en las subclases
    abstract public String getCamaraEnQueTrabaja();
   
    public String toString(){
        Integer datoAnyosParlamento = anyosParlamento;
        return super.toString()+"\nProvincia que representa: "+getProvinciaQueRepresenta()+", años que lleva en el parlamento: "+datoAnyosParlamento.toString()+", cámara en la que trabaja: "+camara;
    }

}

El código de la clase "Diputado":

Código: [Seleccionar]
public class Diputado extends Legislador{
   
    public Diputado(String nombre, String apellidos, int edad, String provinciaQueRepresenta, int anyosParlamento, String camara){
        super(nombre, apellidos, edad, provinciaQueRepresenta, anyosParlamento, camara);
    }
   
    public String getCamaraEnQueTrabaja(){return camara;} //Método abstracto sobreescrito en la clase
}

El código de la clase "Senador":

Código: [Seleccionar]
public class Senador extends Legislador{
   
    public Senador(String nombre, String apellidos, int edad, String provinciaQueRepresenta, int anyosParlamento, String camara){
        super(nombre, apellidos, edad, provinciaQueRepresenta, anyosParlamento, camara);
    }
   
    public String getCamaraEnQueTrabaja(){return camara;}
}

El código de la clase "ListinLegisladores":

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

public class ListinLegisladores{
   
    private ArrayList<Legislador> listinLegisladores;
   
    public ListinLegisladores(){
        listinLegisladores = new ArrayList<Legislador>();
    }
   
    public void addLegislador(Legislador legislador){
        listinLegisladores.add(legislador);
    }
   
    public void imprimirListinLegisladores(){
        System.out.println("VAMOS A PROCEDER A LA IMPRESION DE LA LISTA DE LOS LEGISLADORES: ");
        for(Legislador tmp: listinLegisladores){
            System.out.println(tmp.toString());
        }
        System.out.println("\nAHORA MOSTRAREMOS SOLO LAS CAMARAS EN LAS QUE TRABAJAN LOS SEÑORES LEGISLADORES:");
        for(Legislador tmp: listinLegisladores){
            System.out.println("El legislador: "+tmp.getApellidos()+" trabaja en cámara: "+tmp.getCamaraEnQueTrabaja());
        }
    }
}

El código de la clase "TestClasesYMetodosAbstractos":

Código: [Seleccionar]
public class TestClasesYMetodosAbstractos{
    public static void main(String []Args){
        Diputado diputado1 = new Diputado("Juan","Bigotes",45,"Tarragona",10,"baja");
        Diputado diputado2 = new Diputado("Antonio","Riopérez",40,"Valencia",5,"baja");
        Diputado diputado3 = new Diputado("Eusebio","Tiritón",56,"Castellón",27,"baja");
        Senador senador1 = new Senador("Jose","Trigolimpio",50,"Madrid",15,"alta");
        Senador senador2 = new Senador("Jorge","Lupiañez",67,"Badajóz",40,"alta");
        Senador senador3 = new Senador("Alberto","Pascual",53,"Murcia",19,"alta");
        ListinLegisladores listinLegisladores = new ListinLegisladores();
        listinLegisladores.addLegislador(diputado1);
        listinLegisladores.addLegislador(diputado2);
        listinLegisladores.addLegislador(diputado3);
        listinLegisladores.addLegislador(senador1);
        listinLegisladores.addLegislador(senador2);
        listinLegisladores.addLegislador(senador3);
        listinLegisladores.imprimirListinLegisladores();
    }
}

Tenía una duda. Quería crear un método llamado mostrarCamara() en la clase "Legislador" e invocarlo desde la clase "TestClasesYMetodosAbstractos", pero no funciona del todo bien.

Los dos mencionados códigos anteriormente quedarían así modificados:

El código de la clase "Legislador":

Código: [Seleccionar]
//Creamos una clase de tipo "abstract"
public abstract class Legislador extends Persona{
    private String provinciaQueRepresenta;
    private int anyosParlamento;
    protected String camara;
   
    public Legislador(String nombre, String apellidos, int edad, String provinciaQueRepresenta, int anyosParlamento, String camara){
        super(nombre, apellidos, edad);
        this.anyosParlamento = anyosParlamento;
        this.provinciaQueRepresenta = provinciaQueRepresenta;
        this.camara = camara;
    }
   
    public String getProvinciaQueRepresenta(){return provinciaQueRepresenta;}
    public int getAnyosParlamento(){return anyosParlamento;}
   
    //Creamos un método "abstract" el que no podremos invocar si no lo sobreescribamos en las subclases
    abstract public String getCamaraEnQueTrabaja();
   
    public String toString(){
        Integer datoAnyosParlamento = anyosParlamento;
        return super.toString()+"\nProvincia que representa: "+getProvinciaQueRepresenta()+", años que lleva en el parlamento: "+datoAnyosParlamento.toString()+", cámara en la que trabaja: "+camara;
    }
   
    public void mostrarCamara(Legislador legislador){
        String tmp = "";
        if(legislador instanceof Senador){
            tmp = "Senador ";
        }else{tmp = "Diputado ";}
        System.out.println("El "+tmp+getApellidos()+" trabaja en la cámara: "+camara);
    }
}

en añadido sólo:

Código: [Seleccionar]
public void mostrarCamara(Legislador legislador){
        String tmp = "";
        if(legislador instanceof Senador){
            tmp = "Senador ";
        }else{tmp = "Diputado ";}
        System.out.println("El "+tmp+getApellidos()+" trabaja en la cámara: "+camara);
    }

del código "ListinLegisladores" modificaríamos la parte del método "imprimirListinLegisladores()" de modo que se quedaría así:

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

public class ListinLegisladores{
   
    private ArrayList<Legislador> listinLegisladores;
   
    public ListinLegisladores(){
        listinLegisladores = new ArrayList<Legislador>();
    }
   
    public void addLegislador(Legislador legislador){
        listinLegisladores.add(legislador);
    }
   
    public void imprimirListinLegisladores(){
        System.out.println("VAMOS A PROCEDER A LA IMPRESION DE LA LISTA DE LOS LEGISLADORES: ");
        for(Legislador tmp: listinLegisladores){
            System.out.println(tmp.toString());
        }
        System.out.println("\nAHORA MOSTRAREMOS SOLO LAS CAMARAS EN LAS QUE TRABAJAN LOS SEÑORES LEGISLADORES:");
    }
}

y el código de la clase "TestClasesYMetodosAbstractos" sería así:

Código: [Seleccionar]
public class TestClasesYMetodosAbstractos{
    public static void main(String []Args){
        Diputado diputado1 = new Diputado("Juan","Bigotes",45,"Tarragona",10,"baja");
        Diputado diputado2 = new Diputado("Antonio","Riopérez",40,"Valencia",5,"baja");
        Diputado diputado3 = new Diputado("Eusebio","Tiritón",56,"Castellón",27,"baja");
        Senador senador1 = new Senador("Jose","Trigolimpio",50,"Madrid",15,"alta");
        Senador senador2 = new Senador("Jorge","Lupiañez",67,"Badajóz",40,"alta");
        Senador senador3 = new Senador("Alberto","Pascual",53,"Murcia",19,"alta");
        ListinLegisladores listinLegisladores = new ListinLegisladores();
        listinLegisladores.addLegislador(diputado1);
        listinLegisladores.addLegislador(diputado2);
        listinLegisladores.addLegislador(diputado3);
        listinLegisladores.addLegislador(senador1);
        listinLegisladores.addLegislador(senador2);
        listinLegisladores.addLegislador(senador3);
        listinLegisladores.imprimirListinLegisladores();
        diputado1.mostrarCamara(diputado1);
        diputado1.mostrarCamara(diputado2);
        diputado1.mostrarCamara(diputado3);
        diputado1.mostrarCamara(senador1);
        diputado1.mostrarCamara(senador2);
        diputado1.mostrarCamara(senador3);
    }
}

Pero el resultado no es el que yo esperaba. A la hora de imprimir por pantalla la variable "camara" cojo sólo el valor del primer objeto creado (de los objetos "Diputado" y "Senador"). No entiendo por qué la variable no cambia de valor. Es como si no funcionara, como si fuera una constante.

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

Mario R. Rancel

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

En la clase Persona puedes escribir el método toString más simple (quédate con la idea para situaciones similares):

Código: [Seleccionar]
    public String toString(){
        return "Nombre: "+nombre+" "+apellidos+". Edad: "+edad;
    }

Y todas las declaraciones puedes hacerlas:

Legislador diputado1 = new Diputado("Juan","Bigotes",45,"Tarragona",10,"baja");

En lugar de:

Diputado diputado1 = new Diputado("Juan","Bigotes",45,"Tarragona",10,"baja");

La ventaja de declarar el tipo estático más amplio es que la referencia podrá alojar cualquier tipo de Legislador, en cambio si el tipo estático es Diputado únicamente podrás almacenar en esa referencia a diputados.

Sobre la duda que planteas.

Revísalo con calma porque estás mezclando cosas.

Este método:

Código: [Seleccionar]
    public void mostrarCamara(Legislador legislador){
        String tmp = "";
        if(legislador instanceof Senador){
            tmp = "Senador ";
        }else{tmp = "Diputado ";}
        System.out.println("El "+tmp+getApellidos()+" trabaja en la cámara: "+camara);
    }

Es un método de la clase Legislador, por tanto ya se conoce quién es el Legislador (el propio objeto) ¿Para qué le pasas entonces como parámetro un Legislador?

Basta

    public void mostrarCamara(){
       System.out.println(camara);
    }


Este código tienen poco sentido:

Código: [Seleccionar]
        diputado1.mostrarCamara(diputado1);
        diputado1.mostrarCamara(diputado2);
        diputado1.mostrarCamara(diputado3);
        diputado1.mostrarCamara(senador1);
        diputado1.mostrarCamara(senador2);
        diputado1.mostrarCamara(senador3);

¿Para qué llamas a un método de diputado1 pasándole como parámetro el senador 2 por ejemplo? (además al usar siempre diputado1 siempre te devuelve los datos de diputado1...)

Basta con

        diputado1.mostrarCamara();
        diputado2.mostrarCamara();
        diputado3.mostrarCamara();
        senador1.mostrarCamara();
        senador2.mostrarCamara();
        senador3.mostrarCamara();

Piénsalo con calma

Saludos.

Dimitar Stefanov

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

Gracias por corregirme el ejercicio.

Perdón, me he equivocado en escribir el código, quería escribir:

Código: [Seleccionar]
diputado1.mostrarCamara(diputado1);
        diputado2.mostrarCamara(diputado2);
        diputado3.mostrarCamara(diputado3);
        senador1.mostrarCamara(senador1);
        senador2.mostrarCamara(senador2);
        senador3.mostrarCamara(senador3);

fue un error al utilizar la funcion "ctrl+v" y no modificar después los objetos.

Sobre la explicación del código:

Código: [Seleccionar]
public void mostrarCamara(Legislador legislador){
        String tmp = "";
        if(legislador instanceof Senador){
            tmp = "Senador ";
        }else{tmp = "Diputado ";}
        System.out.println("El "+tmp+getApellidos()+" trabaja en la cámara: "+camara);
    }

no entiendo cómo funcionaría sólo con:

Código: [Seleccionar]
public void mostrarCamara(){
       System.out.println(camara);
    }

porque lo que quiero es que si se trata de un objeto perteneciente al tipo "Diputado" que imprima Diputado y si perteneciera al tipo "Senador" que imprima Senador.

No se me ocurre otro cosa que comprobar que según que objeto pasamos a la función que cambie la variable temporal auxiliar "tmp" de Senador a Diputado y viceversa. Perdona, pero a veces no veo lo más obvio.

Un saludo.

Mario R. Rancel

  • Administrador
  • Experto
  • ********
  • APR2.COM
  • Mensajes: 1978
    • Ver Perfil
Buenos días

No sé si me equivoco... ¿camara no es un atributo del objeto? Pues entonces simplemente lo que hago es recuperar el atributo, según sea el objeto camara ya tendrá un valor u otro

Haz pruebas y pega el código que no te funcione para ver concretamente dónde falla

Saludos.

Dimitar Stefanov

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

Dudo que te hayas equivocado tú, será que no me he explicado yo con propiedad.

Mira, el código de la clase "Legislador" es ese:

Código: [Seleccionar]
//Creamos una clase de tipo "abstract"
public abstract class Legislador extends Persona{
    private String provinciaQueRepresenta;
    private int anyosParlamento;
    protected String camara;
   
    public Legislador(String nombre, String apellidos, int edad, String provinciaQueRepresenta, int anyosParlamento, String camara){
        super(nombre, apellidos, edad);
        this.anyosParlamento = anyosParlamento;
        this.provinciaQueRepresenta = provinciaQueRepresenta;
        this.camara = camara;
    }
   
    public String getProvinciaQueRepresenta(){return provinciaQueRepresenta;}
    public int getAnyosParlamento(){return anyosParlamento;}
   
    //Creamos un método "abstract" el que no podremos invocar si no lo sobreescribamos en las subclases
    abstract public String getCamaraEnQueTrabaja();
   
    public String toString(){
        Integer datoAnyosParlamento = anyosParlamento;
        return super.toString()+"\nProvincia que representa: "+getProvinciaQueRepresenta()+", años que lleva en el parlamento: "+datoAnyosParlamento.toString()+", cámara en la que trabaja: "+camara;
    }
   
    public void mostrarCamara(Legislador legislador){
        String tmp = "";
        if(legislador instanceof Senador){
            tmp = "Senador ";
        }else{tmp = "Diputado ";}
        System.out.println("El "+tmp+getApellidos()+" trabaja en la cámara: "+camara);
    }
}

Y con el método "mostrarCamara" lo que quiero hacer es si le entre un objeto "Senador" cambie la variable temporal "tmp" a "Senador" y si no, que la cambie a "Diputado". Por eso especifico que entrará, en este método, un parámetro de tipo objeto de la clase abstracta "Legislador".

Sí, la variable "camara" es de esta clase, pero quería llegar un poquito más lejos. A lo mejor no era necesario.

Gracias.

 

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".