Foro de elhacker.net

Programación => Java => Mensaje iniciado por: Baal_30 en 5 Mayo 2015, 22:11 pm



Título: Acceder a atributo de subclase
Publicado por: Baal_30 en 5 Mayo 2015, 22:11 pm
Muy buenas. Hoy se me ha planteado una duda que no logro resolver.

He creado 2 clases, Conductor y Taxista (subclase de Conductor).

También he creado un ArrayList<Conductor> para meter instancias de Taxista (porque también he hecho otra clase que hereda de Conductor, y necesito guardarla en el mismo ArrayList). El caso es que no me deja acceder a los atributos ni métodos de Taxista.

Intento este código pero nada : conductores.get(0).getAtributoDelTaxista(); 
Donde conductores es el ArrayList<Conductor> con instancias de Taxista y otra subclase.

Así que esa es mi pregunta, ¿como podría acceder a los atributos y métodos de una subclase?

Gracias.


Título: Re: Acceder a atributo de subclase
Publicado por: PabloPbl en 5 Mayo 2015, 22:50 pm
Eso pasa por que tu estas guardando conductores y no taxistas en tu ArrayList, recuerda que tu haces heredar los taxistas de conductor y no los conductores de taxistas.

En el ArrayList deberías guardar taxistas, y de esa manera ya podrías acceder a los atributos y métodos de la clase "Taxista" y de su superclase que es "Conductor".

Saludos.


Título: Re: Acceder a atributo de subclase
Publicado por: Baal_30 en 5 Mayo 2015, 22:54 pm
Pero, si tengo por ejemplo, Taxistas y Repartidores, ambas clases que derivan de Conductores, y quiero meter instancias de las dos en el mismo arrayList, tendría que hacerlo de Conductores ¿no? Ahí es cuando viene el problema :/


Título: Re: Acceder a atributo de subclase
Publicado por: PabloPbl en 5 Mayo 2015, 23:01 pm
No, lo mas conveniente seria tener un ArrayList para cada trabajo. Si tu haces un ArrayList de conductores, nunca podrás acceder a los atributos de sus subclases. En cambio si lo haces como te digo si podrás, ya que cada trabajo hereda de Conductor y por tanto tienes acceso a los atributos y métodos de las clases de los trabajos.


Título: Re: Acceder a atributo de subclase
Publicado por: Baal_30 en 6 Mayo 2015, 11:57 am
Ya, ya, haciendo dos arrayList diferentes si que se podría, pero yo necesito crear sólo uno...

Entonces es imposible acceder a los datos que quiero de esa manera ¿? :/


Título: Re: Acceder a atributo de subclase
Publicado por: Usuario Invitado en 6 Mayo 2015, 15:42 pm
Ejemplo práctico:

Queremos crear conductores y guardarlos en una lista. Éstos conductores pueden ser de 2 tipos, taxistas o choferes de transporte público. También se deberá recuperar los tipos de conductores de la lista.

Código
  1. public class Conductor {
  2.    private Integer id;
  3.    private String names;
  4.    private String surnames;
  5.    private String dni;
  6.  
  7.    public Conductor() {}
  8.    public Conductor(Integer id, String names, String surnanes,
  9. String dni) {
  10. this.id = id;
  11. this.names = names;
  12. this.surnames = surnames;
  13. this.dni = dni;
  14.    }
  15.    // getters y setters
  16. }
  17.  

Código
  1. public class Taxista extends Conductor {
  2.    private String placaAuto;
  3.    private String horario;
  4.  
  5.    public Taxista() {}
  6.    public Taxista(Integer id, String names, String surnames,
  7. String dni, String placaAuto, string horario) {
  8. super(id, names, surname, dni);
  9. this.placaAuto = placaAuto;
  10. this.horario = horario;
  11.    }
  12.    // getter y setter
  13.    /* si usan getters y setters para los atributos heredados, llamarlos así:
  14.        super.setId(id); // set
  15.        return super.getId(); // get
  16.     */
  17. }
  18.  

Código
  1. public class ConductoresBD {
  2.    private static final List<Conductores> conductores;
  3.    static {
  4. conductores = new ArrayList<>();
  5.    }
  6.    public void insert(Conductor c) {
  7. conductores.add(c);
  8.    }
  9.    public void remove(Conductor c) {
  10. conductores.remove(c);
  11.    }
  12. }

Ahora, hagamos una clase de prueba:

Código
  1. public class Main {
  2.    public static void main(String[] args) {
  3. final ConductoresBD conductores = new Conductores();
  4. Taxista taxista = new Taxista(1, "Juan Manuel", "Figueroa Orellana",
  5. "45930168", "ZK-34539", "A");
  6. conductores.insert(taxista);
  7.  
  8. Conductor c = conductores.get(0);
  9. Taxista retrieved = null;
  10.        if(c instanceof Taxista) {
  11.    retrieved = (Taxista) c;
  12. }
  13. }

La pregunta surge cuando recuperamos los tipos de conductores de la lista, ¿cómo sé qué tipo de objeto he recuperado? Para ésto nos ayudará el operador instanceof:

Código
  1. if(c instanceof Taxista) { /* ... */ }

Lo que el operador instanceof hace es comprobar si el objeto de la izquierda es del mismo tipo que el de la derecha:

Citar
¿c es de tipo Taxista?

La respuesta es afirmativa. Por lo tanto, podemos hacer un casting (convertir) del objeto padre hacia el objeto hijo:

Código
  1. Taxista retrieved = (Taxista) c;

Y podemos usar los métodos de Taxista:

Código
  1. retrieved.setPlacaAuto("TK-45905");
  2. retrieved.setHorario("C");


Espero se haya entendido el mensaje. Saludos.


Título: Re: Acceder a atributo de subclase
Publicado por: PabloPbl en 6 Mayo 2015, 16:38 pm
Ya, ya, haciendo dos arrayList diferentes si que se podría, pero yo necesito crear sólo uno...

Entonces es imposible acceder a los datos que quiero de esa manera ¿? :/

No es imposible, lo que yo he puesto ahí, es una manera sencilla y mas fácil de hacer, pero si insistes con querer hacerlo así, tenes que tener mas conocimientos en el tema, la respuesta que publico Gus es especial para lo que quieres.

Saludos!


Título: Re: Acceder a atributo de subclase
Publicado por: Baal_30 en 6 Mayo 2015, 22:47 pm
Gus me encantan tus respuestas, pero me cuesta muchísimo entenderlas, jaja, aunque es como más aprendo :) más o menos me ha quedado claro, lo que no entiendo es porque creas ConductoresBD y el arrayList ahí, pudiendolo hacer en el main así :
Código
  1. ArrayList<Conductores> conductores = new ArrayList<Conductores>();
¿no?

Yo lo que intenté usar es getClass, pero no se utilizarlo :/ No conocía que instanceof lo hace así de fácil.

Gracias por las respuestas ¡!