Duda con Polimorfismo

Hola, estoy haciendo mi curso para certificacion y me surgio una duda espero alguien me pueda ayudar.

En cuanto las colecciones, cual es el motivo de hacer la referencia generalizada

List lista = ArrayList();

existe alguna diferencia al hacer esto?

ArrayList<> lista = ArrayList();

No entiendo muy bien el echo de generalizar a la clase base, se utilizarlo pero quisiera saber mas como la explicacion tecnica de porque se generaliza?

Padre obj = new HIjo();

Muchas gracias. espero puedan ayudarme con mi duda

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Sr. Negativo

Re: Duda con Polimorfismo

No entiendo muy bien el echo de generalizar a la clase base, se utilizarlo pero quisiera saber mas como la explicacion tecnica de porque se generaliza?

Padre obj = new HIjo();

Tal vez un ejemplo te sirva(eso es sobre herencia):

public class Main{
 
public static void main(String[] args) {
Nieto nieto=new Nieto();
Papa papa=new Papa();
Abuelo abuelo=new Abuelo();
 
nieto.setNombre("Daniel");
nieto.setApellidoPaterno("Torres");
nieto.setApellidoMaterno("Garcia");
nieto.setEdad(12);
nieto.verDatos();
 
papa.setNombre("Pedro");
papa.setApellidoPaterno("Torres");
papa.setApellidoMaterno("Alcantara");
papa.setEdad(34);
papa.setOficio("mecanico");
papa.verDatos();
 
abuelo.setNombre("Tomas");
abuelo.setApellidoPaterno("Torres");
abuelo.setApellidoMaterno("Garcia");
abuelo.setEdad(89);
abuelo.setId_Carnet("TTG39292");
abuelo.verDatos();
}

 
}
 
interface Servicios{
public abstract void verDatos();
}
 
 
abstract class Persona implements Servicios{
private String nombre;
private String apellidoPaterno;
private String apellidoMaterno;
private int edad;
public Persona(){}
public Persona(String nombre, String apelllidoPaterno,String apellidoMaterno,int edad){
this.setNombre(nombre);
this.setApellidoPaterno(apellidoPaterno);
this.setApellidoMaterno(apellidoMaterno);
this.setEdad(edad);
}
public Persona(String nombre){
this(nombre,"","",0);
}
public Persona(int edad){
this("","","",edad);
}
public Persona(String nombre, String apelllidoPaterno,String apellidoMaterno){
this(nombre, apelllidoPaterno,apellidoMaterno,0);
}
public String toString(){
return "nombre: "+this.getNombre()+", apellido paterno: "+this.getApellidoPaterno()+", apellido materno: "+this.getApellidoMaterno()+", edad: "+this.getEdad();
}
public abstract double getPulsaciones();
 
public String getApellidoMaterno() {
return apellidoMaterno;
}
 
public void setApellidoMaterno(String apellidoMaterno) {
this.apellidoMaterno = apellidoMaterno;
}
 
public String getApellidoPaterno() {
return apellidoPaterno;
}
 
public void setApellidoPaterno(String apellidoPaterno) {
this.apellidoPaterno = apellidoPaterno;
}
 
public int getEdad() {
return edad;
}
 
public void setEdad(int edad) {
this.edad = edad;
}
 
public String getNombre() {
return nombre;
}
 
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
 
 
 
class Abuelo extends Persona{
private String id_carnet;
Abuelo(){}
Abuelo(String id){
id_carnet=id;
}
Abuelo(String nombre, String apellidoPaterno,String apellidoMaterno,int edad,String id){
super(nombre, apellidoPaterno,apellidoMaterno,edad);
id_carnet=id;
}
protected void setId_Carnet(String id){
this.id_carnet=id;
}
protected String getId_Carnet(){
return this.id_carnet;
}
 
@Override
public void verDatos() {
System.out.println("Datos:\t "+toString());    
}
@Override
public String toString(){
return super.toString()+", id: "+this.id_carnet;
}
 
@Override
public double getPulsaciones() {
return (220.0-super.getEdad())/15.0;
}
 
}
 
class Papa extends Abuelo{
private String oficio;
Papa(){}
Papa(String oficio){
this.setOficio(oficio);
}
Papa(String nombre, String apellidoPaterno,String apellidoMaterno,int edad,String id,String oficio){
super(nombre, apellidoPaterno,apellidoMaterno,edad,"");
this.setOficio(oficio);
}
 
public String getOficio() {
return oficio;
}
 
public void setOficio(String oficio) {
this.oficio = oficio;
}
@Override
public String toString(){
return super.toString()+", oficio: "+this.oficio;
}
}
 
 
class Nieto extends Papa{

}

Gracias

sip muchas gracias... me gustaria saber mas al respecto en cuanto ala teoria, de generalizar en el polimorfismo....

Imagen de julgo

la diferencia esta en que con

la diferencia esta en que con :
List lista=new ArrayList(); pierdes los metodos específicos de arraylist ,pero tu código es mas flexible ya que tiene la misma funcionalidad con otras implementaciones que quieras cambiar o aumentar digamos
List lista2=new LinkedList(); y con eso por ejemplo puedes reusar código asi un método que reciba tanto el arraylist como el linkedlist e imprima los elementos

public void imprime(List lista) {
//hacer el for
      System.out.println(lista.get(o));
}

Se recomienda programar a la

Se recomienda programar a la interfaz ( al conjunto de métodos que quieres llamar ) y no a la implementación para que el código no quede tan acoplado.

Dicho de otra forma, si tuvieras un metodo que recibiera:

public void someMethod( ArrayList list ) {
...
}

Estarias amarrando a que SOLO le puedas pasar instancias de ArrayList.

En cambio si se declara:

public void someMethod( List list ) {
...
}

Podrias llamarlo asi:

someMethod(new LinkedList() );

O con cualquiera de las clases que implementan la interfaz list ( http://docs.oracle.com/javase/7/docs/api/java/util/List.html )

Imagen de echan

En realidad usar una

En realidad usar una implementacion concreta como ArrayList o LinkedList en lugar de la interfaz List, es un tema de acoplamiento como comenta @OscarRyz y poco tiene que ver con el polimorfismo. El polimorfismo es otra cosa.

El polimorfismo, en el caso de tu ejemplo es el polimorfismo paramétrico (genericos en el mundo Java) y se manifiesta cuando creas componentes o algoritmos que operan sobre objetos sin especificar.

Por ejemplo:
El ArrayList es un estructura polimorfica, si ves el método add(E e), "E" representa el tipo de un objeto que no sabemos que es hasta que se cree una instancia de ArrayList con el parámetro de clase, es decir, el código de add está escrito de forma generica, entonces cuado creas:

ArrayList<Padre> lista = ArrayList();

"Padre" es el parametro de clase de ArrayList y es en ese momento "E" en el método add se veria imaginariamente como add(Padre e) para la instancia lista que se creó.

Las ventajas de los genericos es la garantia de la verificación estática, usar genéricos te garantiza que el compilador te diga cuando no estas usando un método con el tipo de dato adecuado, o usar estructuras de control como el for sin tener que inspeccionar en runtime el tipo de objeto sobre la lista, o tambien reusar componentes o algoritmos genericos.

En fin tiene varias ventajas .. pero tambien habria que decir que incidentalmente trae cosas extrañas y un poco bizarras. Cuando mezclas polimorfismo parametrico + herencia(subtyping) incidentalmente tienes covarianza y contravarianza.

Imagen de bferro

Cuidado con mezclar genéricos con raw types

En el código que escribes con anterioridad (lo escribo otra vez):

ArrayList<Padre> lista = ArrayList();

estás mezclando incorrectamente los tipos genéricos con los tipos raw, que el lenguaje ha tenido que mantener para que el código anterior a Java 5 pueda seguir corriendo. Cuando compilas un programa que incluye esa línea obtendrás un warning del compilador:

Note: tu programa.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Desafortunadamente muchos no atienden a esos warnings. El mezclar genéricos con raw types puede provocar errores y sorpresas. Pongo un código de ejemplo:

ArrayList foo = new ArrayList();
ArrayList<Integer> bar;
// Después de algunas líneas

bar = foo;
foo.add("alien");
foo.add(new Float(3.1416);
System.out.println(bar);      // Imprime [abc, 3.1416]
// ¿No qué bar era una lista exclusiva para objetos Integer?

Los <> deciden muchas cosas. No hay que olvidarse de ellos cuando se crea el objeto que vas a usar como implementación.

ArrayList<Padre> lista = ArrayList<>();
Imagen de echan

cierto, estaba ilustrando el

cierto, estaba ilustrando el parámetro de clase y no le puse atencion a la linea completa. Pero como dices lo que ilustras es origen de muchos dolores de cabeza .. pero ya poniendonos mas especiales esa linea esta lejos de compilar porque además del operador diamond falta el keyword new ... :)

  ArrayList<Padre> lista = new ArrayList<>();
Imagen de bferro

No es ponernos más especiales

Dejé tu línea tal y como estaba que por supuesto es errónea y no era lo que quería comentar. La intención de mi comentario no es para eso de ponernos más especiales. Cada cual acepta las opiniones de otros como mejor le plazca.