Preguntas herencia, polimorfismo

Estoy intentando aprender a programar en Java, ya que tengo un examen en pocos días, y tengo una duda.
No sé muy bien como se utiliza el casting en la herencia, es decir la teoría que yo tengo la leo y la requeteleo pero no saco nada en claro y no encuentro nada práctico con lo que entenderlo ya que el ejemplo que yo tengo me da confusión, puesto que no entiendo la direferencia entre el casting y 'super'.
Y con el instanceof entiendo un poco más pero a la hora de ponerlo en práctica me pasa igual.
Tengo otra duda... Cuando sé cuando una clase a de ser abstracta, es decir, ¿cuándo sé cuando un método a de ser abstracto? ¿Cuándo en las otras clases se utilice ese método pero en cada clase de forma distinta? Eso pasa con más métodos que no son abstractos ¿no?
Si pudiera explicármelo se lo agradecería tengo un examen en pocos días y me quedan esas dudas...

1 Respuesta

Respuesta
1
Es normal que tengas dudas sobre esos temas, que son los más enrevesados de Java o de la POO. Intentaré ponerte un ejemplo muy habitual para ver si te aclaras.
La clase AbstractList. Es una clase importante en Java ya que de ella heredan las colecciones habituales(Arraylist y Vector). Esta clase define los métodos (porque implementa la clase Collection) que debe tener una colección, es decir, los de añadir o quitar elementos, ver si la colección tiene un elemento concreto, etc... No tiene sentido que los implemente, ya que cada colección hija lo hará de una manera diferente (Vector lo hace con métodos sincronizados, que permiten concurrencia, y Arraylist no, ya que no busca concurrencia), por eso la clase AbstractList es abstracta y algunos métodos lo son también. Pero podría tener algún método que vayan a usar todos o algunos de sus hijos sin cambiarlo, y entonces implementarlo.
Cuando se quiere una clase que no implemente nada, que solo defina los métodos y que sus "descendientes" hagan todo es cuando se hace una Interfaz. En nuestro ejemplo la interfaz es Collection.
Si hacemos un método que va a devolver una colección, podríamos definirlo que devuelva un Arraylist o un Vector, pero mejor aún es hacer que devuelve una Collection, porque así no tenemos que saber si lo que devuelve es un Arraylist o un Vector, y aún así podremos usar los métodos básicos que hemos dicho de una colección (add, remove, ...). Incluso podemos cambiar el contenido del método para devolver una colección de un tipo o de otra, que donde se use ese método no habrá que tocar nada. Si donde se use queremos hacer algo que solo un Vector puede hacer, entonces haremos el casting a Vector. Si dependiendo de si es un Vector o un Arraylist se hacen cosas diferentes, es cuando usaremos instanceof, para hacer lo que queramos. Pongo un ejemplo sencillo:
public Collection<String> dameColeccion(){ //No es obligatorio pero es recomendable especificar que lleva la collecion, en este caso Strings
...
...
return Vector o return Arraylist;
}
public void unMetodo(){
// Cojo la coleccion, me da igual que es
Collection<String> miColeccion = dameColeccion();
String cadena="cadena";
// Meto la cadena en la coleccion, y sigue dandome igual que es
miColeccion.add(cadena);
// Tambien la puedo recorrer o lo que quiera con ella
//Ahora quiero ver que es
if (miColeecion instanceof ArrayList) {
System.out.println("Es un arrayist...");
//Entonces puedo coger el ArrayList
ArrayList<String> miArrayList = (ArrayList) miColeccion;
...
}
else if (miColeccion instanceof Vector) {
System.out.println("Es un vector...");
Vector<String> miVector = (Vector) miColeccion;
...
}
else System.out.println("Es otra cosa...");
}
Me has aclarado bastante!
Muchísimas gracias y gracias sobretodo por responder tan pronto.
Lo que me queda duda entonces es en cuando una clase tiene que ser o no abstracta...
Si me lo puedes explicar seria genial, si no, no pasa nada y te daré todos los puntos porque vamos menudo lujo el contestar rapido y así de bien.
Muy amable!
No hay de qué,
una clase será abstracta o no según se decida, no hay ninguna ley para eso. A la hora de decidir se hace una simple pregunta ¿quiero o necesito un objeto de esa clase concreta o solo de sus hijas?. Si no necesito ni quiero un objeto de esa clase, entonces esa clase solo sirve para que sus hijas hereden atributos y métodos (implementados o no), entonces la defino como clase abstracta, ya que las clases abstractas NO se pueden instanciar, no se pueden crear objetos de esa clase (por estar definida como abstracta, y además porque probablemente tenga definidos métodos sin implementación, y un objeto con un método sin implementar sería absurdo y peligroso). Otra cosa es yo podré manejar cualquier objeto de una clase hija usando esa clase (como vimos con Collection antes, aunque Collection es interfaz)
Y ahora preguntarás, si una interfaz es una clase que define métodos pero no implementa nada para que otras clases los hereden e implementen, ¿por qué no es una clase abstracta en vez de una interfaz? Hay varias razones para ello, pero la más entendible e inmediata es que, como habrás estudiado, la ley de Java dice que una clase solo puede heredar (ser hija) de UNA SOLA clase (un solo "extends"). Entonces, para que una clase pueda "heredar" métodos de muchas más clases lo que se hace es que implemente una serie de Interfaces (puede haber varios "implements").
En nuestro ejemplo, un ArrayList extiende (es hija) solo de AbstractList pero también implementa la interfaz List (que a su vez implementa Collection), y gracias a ello sabemos que un ArrayList tiene los métodos básicos de una colección. También implementa las interfaces Serializable (importante para poder mandar un Arraylist a disco o por la red, convirtiéndolo en una serie de bytes), Cloneable (perimte crear copias de los objetos), Iterable<E> (Permite usar un objeto iterador para recorrerla) y RandomAccess (que nos dice que se puede acceder a cualquier objeto que la compone en un tiempo constante, es decir, hacerle un get(index) )

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas