¿Cuál es la principal diferencia entre herencia y polimorfismo?

172

Hoy me presentaron esta pregunta en un examen de libro abierto al final del módulo y me encontré perdido. Estaba leyendo Head first Javay ambas definiciones parecían ser exactamente las mismas. Me preguntaba cuál era la diferencia PRINCIPAL para mi propia mentalidad. Sé que hay varias preguntas similares a esto, pero no he visto ninguna que proporcione una respuesta definitiva.

Darren Burgess
fuente
2
De alguna manera relacionado con esta pregunta: ¿Es posible el polimorfismo sin herencia?
Edwin Dalorzo

Respuestas:

289

La herencia es cuando una 'clase' deriva de una 'clase' existente. Entonces, si tiene una Personclase, entonces tiene una Studentclase que se extiende Person, Student hereda todas las cosas que Persontiene. Hay algunos detalles sobre los modificadores de acceso que pones en los campos / métodos en Persona, pero esa es la idea básica. Por ejemplo, si tiene un campo privado activado Person, Studentno lo verá porque sus campos privados y privados no son visibles para las subclases.

El polimorfismo se ocupa de cómo el programa decide qué métodos debe usar, según el tipo de cosa que tenga. Si tiene un Person, que tiene un readmétodo, y tiene uno Studentque se extiende Person, que tiene su propia implementación read, el método de ejecución determina el método al que llama, dependiendo de si tiene a Persono a Student. Se pone un poco complicado, pero si haces algo como

Person p = new Student();
p.read();

se llama al método de lectura en Student . Eso es el polimorfismo en acción. Puede hacer esa tarea porque a Student es a Person , pero el tiempo de ejecución es lo suficientemente inteligente como para saber que el tipo real pes Student .

Tenga en cuenta que los detalles difieren entre los idiomas. Puede hacer herencia en JavaScript, por ejemplo, pero es completamente diferente de la forma en que funciona en Java.

hvgotcodes
fuente
9
@ hvgtcodes, en pocas palabras, la relación superclase-subclase es la herencia y el concepto de implementación del mismo método de una manera diferente entre la clase principal y sus subclases, y llamarlas según la situación son Polimorfismo. ¿Estoy en lo correcto?
Muhammad Raihan Muhaimin
1
@hvgotcodes pero digamos que si Personel readmétodo está usando un modificador de acceso público, ¿no podrán los Studentobjetos acceder a ellos? y entonces Student s = new Student();no será más fácil? Todavía no obtengo los beneficios del polimorfismo.
Scorpiorian83
1
@hvgotcodes Student s = new Student () funcionaría. Pero digamos después de que escribiste mucho código usando esta idea, y luego te das cuenta de que cometiste un error. La persona en realidad no es un estudiante, es un maestro. Entonces, simplemente podría cambiar de Persona p = nuevo Estudiante () a Persona p = nuevo Maestro (), y luego hará su vida mucho más simple.
munmunbb
Mi pregunta aquí sería ¿por qué querrías usar en Person p = new Student();lugar de Student p = new Student();?
PerfectContrast
@PerfectContrast Creo que es útil cuando quieres tener un estudiante, conductor, maestro, etc. como Persona y los agrupas en una Lista o algo así. Entonces, cuando llamas 'leer' para todos, todos llaman a su propio método 'leer'.
Savante
205

La herencia se refiere al uso de la estructura y el comportamiento de una superclase en una subclase.

El polimorfismo se refiere a cambiar el comportamiento de una superclase en la subclase.

Ted Hopp
fuente
55
¿Esta respuesta implica que el polimorfismo requiere herencia?
jaco0646
66
@ jaco0646 - En el contexto de Java, creo que sí. (En otros idiomas, quizás no tanto). Tenga en cuenta que "superclase" y "subclase" se usan libremente aquí. El polimorfismo también podría significar la herencia del comportamiento especificado (pero no implementado) en una interfaz.
Ted Hopp
1
@AlirezaRahmani - No entiendo tu comentario. ¿Quiere decir que la herencia no implica heredar propiedades y comportamiento? Eso sería contrario a cómo Java (y la mayoría de los lenguajes orientados a objetos y basados ​​en clases) definen la herencia. De la Especificación del lenguaje Java, §8.4.8 : "Una clase C hereda de su superclase directa todos los métodos concretos m(ambos staticy instance) de la superclase para la cual ..." (seguido de detalles sobre la herencia). Suena como "reutilización de código" para mí.
Ted Hopp
La herencia de @TedHopp es principalmente una herramienta polimórfica, pero algunas personas, para su posterior peligro, intentan usarla como una forma de reutilizar / compartir código. La razón es "bueno si heredo, entonces obtengo todos los métodos de forma gratuita", pero ignorando el hecho de que estas dos clases potencialmente no tienen una relación polimórfica.
Alireza Rahmani Khalili
1
@AlirezaRahmani: en Java (que es sobre lo que OP preguntó específicamente, según las etiquetas), la herencia de clase definitivamente implica un comportamiento de herencia. Eso es parte de la definición del lenguaje. El hecho de que esto pueda ser mal utilizado como lo describe es una de las debilidades de Java. (Una debilidad relacionada implicaba declarar clases para implementar interfaces simplemente para importar las constantes definidas en la interfaz. Finalmente, los diseñadores de Java introdujeron import staticpara eliminar este mal uso de las interfaces.) Para el polimorfismo puro en Java, la herramienta a utilizar es interfaces, no herencia de clase.
Ted Hopp
63

Polimorfismo : la capacidad de tratar objetos de diferentes tipos de manera similar. Ejemplo: la jirafa y el cocodrilo son animales, y los animales pueden Move. Si tiene una instancia de un Animal, puede llamar Movesin saber o preocuparse de qué tipo de animal es.

Herencia : esta es una forma de lograr tanto el polimorfismo como la reutilización de código al mismo tiempo.

Otras formas de polimorfismo : hay otra forma de lograr el polimorfismo, como las interfaces, que solo proporcionan polimorfismo pero no reutilizan el código (a veces, el código es bastante diferente, por ejemplo, Movepara una Serpiente sería muy diferente de Movepara un Perro, en cuyo caso Una interfaz sería la mejor opción polimórfica en este caso.

En otros lenguajes dinámicos, se puede lograr el polimorfismo con Duck Typing, que es que las clases ni siquiera necesitan compartir la misma clase base o interfaz, solo necesitan un método con el mismo nombre. O incluso más dinámico como Javascript, ni siquiera necesita clases, solo un objeto con el mismo nombre de método puede usarse polimórficamente.

Davy8
fuente
17

La principal diferencia es que el polimorfismo es un resultado específico de la herencia. El polimorfismo es donde el método a invocar se determina en tiempo de ejecución en función del tipo de objeto. Esta es una situación que se produce cuando una clase hereda de otra y anula un método en particular. Sin embargo, en un árbol de herencia normal, no tiene que anular ningún método y, por lo tanto, no todas las llamadas a métodos deben ser polimórficas. ¿Tiene sentido? Es un problema similar a todos los vehículos Ford que son automóviles, pero no todos los automóviles son Ford (aunque no del todo ...).

Además, el polimorfismo se ocupa de la invocación de métodos, mientras que la herencia también describe miembros de datos, etc.

Chris Thompson
fuente
12

En Java, los dos están estrechamente relacionados. Esto se debe a que Java utiliza una técnica para invocar métodos llamada "despacho dinámico". Si tengo

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

Entonces vemos que hereda B spinde A. Sin embargo, cuando tratamos de manipular el objeto como si se tratara de un tipo A, todavía nos llegan comportamiento de B para draw. El drawcomportamiento es polimórfico.

En algunos idiomas, el polimorfismo y la herencia no están tan estrechamente relacionados. En C ++, por ejemplo, las funciones no declaradas virtuales se heredan, pero no se enviarán dinámicamente, por lo que no obtendrá ese comportamiento polimórfico incluso cuando use la herencia.

En javascript, todas las llamadas a funciones se envían dinámicamente y tiene una escritura débil. Esto significa que podría tener un montón de objetos no relacionados, cada uno con los suyos draw, tener una función iterar sobre ellos y llamar a la función, y cada uno se comportaría bien. Tendría su propio dibujo polimórfico sin necesidad de herencia.

ccoakley
fuente
12

Polimorfismo: suponga que trabaja para una empresa que vende bolígrafos. Así que haces una clase muy agradable llamada "Bolígrafo" que maneja todo lo que necesitas saber sobre un bolígrafo. Usted escribe todo tipo de clases para facturación, envío, creación de facturas, todo utilizando la clase Pluma. Un día llega el jefe y dice: "¡Buenas noticias! ¡La compañía está creciendo y ahora estamos vendiendo libros y CD!" No son buenas noticias porque ahora tienes que cambiar cada clase que usa Pen para usar también Book & CD. Pero, ¿qué pasaría si originalmente hubiera creado una interfaz llamada "SellableProduct" y Pen implementara esta interfaz? Entonces podría haber escrito todas sus clases de envío, facturación, etc. para usar esa interfaz en lugar de Pen. Ahora todo lo que tendría que hacer es crear una nueva clase llamada Book & CompactDisc que implemente la interfaz SellableProduct. ¡Debido al polimorfismo, todas las otras clases podrían continuar trabajando sin cambios! ¿Tener sentido?

Entonces, significa usar Herencia, que es una de las formas de lograr el polimorfismo.

El polimorfismo puede ser posible en una clase / interfaz pero la herencia siempre entre 2 o más clases / interfaces. La herencia siempre conforma la relación "es-a" mientras que no siempre es con el polimorfismo (que puede conformar ambas relaciones "es-a" / "tiene-a".

AmitK
fuente
6

La herencia es más una cosa estática (una clase se extiende a otra) mientras que el polimorfismo es una cosa dinámica / tiempo de ejecución (un objeto se comporta de acuerdo con su tipo dinámico / tiempo de ejecución no a su tipo estático / declaración).

P.ej

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

-> Aunque el tipo estático / declaración de a es A, el tipo dinámico / tiempo de ejecución real es B y, por lo tanto, a.foo () ejecutará foo como se define en B y no en A.

Pardo rojizo
fuente
3

El polimorfismo es un enfoque para expresar un comportamiento común entre tipos de objetos que tienen rasgos similares. También permite que se creen variaciones de esos rasgos mediante la anulación. La herencia es una forma de lograr el polimorfismo a través de una jerarquía de objetos donde los objetos expresan relaciones y comportamientos abstractos. Sin embargo, no es la única forma de lograr el polimorfismo. El prototipo es otra forma de expresar el polimorfismo que es diferente de la herencia. JavaScript es un ejemplo de un lenguaje que usa prototipos. Me imagino que también hay otras formas.

perezoso
fuente
3

La herencia es un concepto relacionado con la reutilización de código. Por ejemplo, si tengo una clase principal, digamos, Animaly contiene ciertos atributos y métodos (para este ejemplo, di makeNoise()y sleep()) y creo dos clases secundarias llamadas Dogy Cat. Dado que tanto los perros como los gatos se duermen de la misma manera (supongo) no hay necesidad de agregar más funcionalidad al sleep()método en las subclases Dogy Catproporcionadas por la clase principal Animal. Sin embargo, un Dogladrido y una clase pueden tener un método para hacer ruido, un perro y un gato hacen ruidos diferentes entre sí y con otros animales. Por lo tanto, existe la necesidad de redefinir ese comportamiento para sus tipos específicos. De ahí la definición de polimorfismo. Espero que esto ayude.Cat maúlla, aunque elAnimal

vengador12
fuente
3

La documentación de Oracle cita la diferencia con precisión.

herencia: una clase hereda campos y métodos de todas sus superclases, ya sean directas o indirectas. Una subclase puede anular los métodos que hereda o puede ocultar los campos o métodos que hereda . (Tenga en cuenta que ocultar campos es generalmente una mala práctica de programación).

polimorfismo: el polimorfismo se refiere a un principio en biología en el que un organismo o especie puede tener muchas formas o etapas diferentes. Este principio también se puede aplicar a la programación orientada a objetos y lenguajes como el lenguaje Java. Las subclases de una clase pueden definir sus propios comportamientos únicos y, sin embargo, compartir parte de la misma funcionalidad de la clase principal.

el polimorfismo no es aplicable para campos.

Publicación relacionada:

Polimorfismo vs anulación vs sobrecarga

Ravindra babu
fuente
1

El polimorfismo es un efecto de la herencia . Solo puede suceder en clases que se extienden entre sí. Le permite llamar a métodos de una clase sin saber el tipo exacto de la clase. Además, el polimorfismo ocurre en tiempo de ejecución .

Por ejemplo, ejemplo de polimorfismo de Java:

ingrese la descripción de la imagen aquí

La herencia permite que las clases derivadas compartan interfaces y códigos de sus clases base. Sucede en tiempo de compilación .

Por ejemplo, todas las clases en la plataforma Java son descendientes de objetos (imagen cortesía de Oracle):

ingrese la descripción de la imagen aquí

Para obtener más información sobre la herencia de Java y el polimorfismo de Java

Johnny
fuente
0

La herencia es cuando la clase A hereda todos los métodos / campos públicos / protegidos no estáticos de todos sus padres hasta Object.

Cosmin Cosmin
fuente
0

Si usa JAVA es tan simple como esto:

El polimorfismo está utilizando métodos heredados, pero "anularlos" para hacer algo diferente (o lo mismo si lo llamas super, técnicamente no sería polimórfico).

Corrígeme si me equivoco.

Oliver Dixon
fuente
0

El objetivo principal del polimorfismo : crear una variable de referencia para la superclase y mantener la subclase object => un objeto puede realizar múltiples comportamientos .

En herencia , la subclase hereda las propiedades de la superclase .

satya
fuente
0

La herencia es una especie de polimorfismo. De hecho, la herencia es el polimorfismo dinámico. Entonces, cuando eliminas la herencia, ya no puedes anularla.

Alireza Rahmani Khalili
fuente
0

Con Herencia, la implementación se define en la superclase, por lo que el comportamiento se hereda.

class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;

Con Polymorphism, la implementación se define en la subclase, por lo que solo se hereda la interfaz .

interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}
mherzl
fuente
0

El polimorfismo se logra por herencia en Java.

├── Animal
└── (instances)
    ├── Cat
    ├── Hamster
    ├── Lion
    └── Moose

├── interface-for-diet
   ├── Carnivore
   └── Herbivore
├── interface-for-habitat
   ├── Pet
   └── Wild

public class Animal {
    void breath() {
    };
}

public interface Carnivore {
    void loveMeat();
}

public interface Herbivore {
    void loveGreens();
}

public interface Pet {
    void liveInside();
}

public interface Wild {
    void liveOutside();
}

public class Hamster extends Animal implements Herbivore, Pet {

    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbor is a Gerbil");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
    }
}

public class Cat extends Animal implements Carnivore, Pet {
    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbr is a Gerbil");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Tuna, Chicken, and More");
    }
}

public class Moose extends Animal implements Herbivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat grass");
    }
}

public class Lion extends Animal implements Carnivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Moose");
    }
}

Hamsterclase hereda la estructura de Animal, Herbivorey Petexhibir el conductismo polimórfica de una mascota doméstica.

Catclase hereda la estructura de Animal, Carnivorey Petque también exhiben conductismo polimórfica de una mascota doméstica.

nabster
fuente