Acceder a atributo de subclase

Iniciado por Baal_30, 5 Mayo 2015, 22:11 PM

0 Miembros y 1 Visitante están viendo este tema.

Baal_30

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.
«La suerte es el cuidado de los detalles». -Winston Churchill

PabloPbl

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.

Baal_30

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 :/
«La suerte es el cuidado de los detalles». -Winston Churchill

PabloPbl

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.

Baal_30

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 ¿? :/
«La suerte es el cuidado de los detalles». -Winston Churchill

Usuario Invitado

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 (java) [Seleccionar]
public class Conductor {
    private Integer id;
    private String names;
    private String surnames;
    private String dni;

    public Conductor() {}
    public Conductor(Integer id, String names, String surnanes,
String dni) {
this.id = id;
this.names = names;
this.surnames = surnames;
this.dni = dni;
    }
    // getters y setters
}


Código (java) [Seleccionar]
public class Taxista extends Conductor {
    private String placaAuto;
    private String horario;

    public Taxista() {}
    public Taxista(Integer id, String names, String surnames,
String dni, String placaAuto, string horario) {
super(id, names, surname, dni);
this.placaAuto = placaAuto;
this.horario = horario;
    }
    // getter y setter
    /* si usan getters y setters para los atributos heredados, llamarlos así:
       super.setId(id); // set
       return super.getId(); // get
    */
}


Código (java) [Seleccionar]
public class ConductoresBD {
    private static final List<Conductores> conductores;
    static {
conductores = new ArrayList<>();
    }
    public void insert(Conductor c) {
conductores.add(c);
    }
    public void remove(Conductor c) {
conductores.remove(c);
    }
}


Ahora, hagamos una clase de prueba:

Código (java) [Seleccionar]
public class Main {
    public static void main(String[] args) {
final ConductoresBD conductores = new Conductores();
Taxista taxista = new Taxista(1, "Juan Manuel", "Figueroa Orellana",
"45930168", "ZK-34539", "A");
conductores.insert(taxista);

Conductor c = conductores.get(0);
Taxista retrieved = null;
        if(c instanceof Taxista) {
    retrieved = (Taxista) c;
}
}


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 (java) [Seleccionar]
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 (java) [Seleccionar]
Taxista retrieved = (Taxista) c;

Y podemos usar los métodos de Taxista:

Código (java) [Seleccionar]
retrieved.setPlacaAuto("TK-45905");
retrieved.setHorario("C");



Espero se haya entendido el mensaje. Saludos.
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

PabloPbl

Cita de: 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 ¿? :/

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!

Baal_30

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 (java) [Seleccionar]
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 ¡!
«La suerte es el cuidado de los detalles». -Winston Churchill