2011-04-04 9 views
9

Sé un poco qué es el polimorfismo pero no pude entenderlo claramente. También mi código es el siguiente:¿Es este el ejemplo del polimorfismo?

class Human 
{ 
    public virtual void CleanTheRoom() 
    { 
    } 
} 
class Woman:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //women clean faster 
    } 
} 
class Man:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //men clean slower, different code here 
    } 
} 
class Child:Human 
{ 
    public override void CleanTheRoom() 
    { 
    //empty ... children are lazy :) 
    } 
} 

¿Debo explicar esto es polymorhism porque todas las clases derivadas de la clase base humana contienen método CleanTheRoom pero cada uno de ellos se pone en práctica de manera diferente?

+1

Mejor stil sería poner la definición del método CleanTheRoom en una interfaz 'IClean' e implementar eso para los tipos de humanos que pueden limpiar. Entonces obtienes polimorfismo libre al poder enviar estos humanos a esta interfaz. – ChristopheD

+29

Definitivamente es un ejemplo de sexismo. – juharr

+1

@juharr y agism. – kenny

Respuesta

21

El beneficio del polimorfismo viene cuando desea invocar el método CleanTheRoom() en algún tipo de Human, pero no le importa cuál específicamente.

Al tener CleanTheRoom() definido en el nivel de la clase base, Human, se puede escribir código más corto, más limpio en la aplicación de cualquier otro lugar cuando se está trabajando con una instancia de Human, ya sea un Man, Woman, o Child.

polimorfismo, por ejemplo, le permite evitar las sentencias condicionales feas donde se verifica de forma explícita para cada tipo de Human y llama a un método diferente:

bueno:

private void SomeMethod(Human h) 
{ 
    //some logic 
    h.CleanTheRoom(); 
    //more logic 
} 

malo:

private void SomeMethod(Human h) 
{ 
    //some logic 
    if (h is Man) 
     CleanRoomSlowly(); 
    else if (h is Woman) 
     CleanRoomQuickly(); 
    else if (h is Child) 
     GoofOff(); 
    //some logic 
} 
+0

También es una buena respuesta, por las mismas razones expresadas en el comentario a JacobM. – riwalk

16

Lo que tienes es un buen ejemplo le de herencia. El polimorfismo se refiere específicamente a la posibilidad de referirse a objetos de diferentes tipos mediante el uso de un solo tipo (la clase o interfaz principal), algo que este tipo de herencia hace posible. De esta manera:

List<Human> humans = new ArrayList<Human>(); 

humans.add(new Woman()); 
humans.add(new Woman()); 
humans.add(new Man()); 
humans.add(new Child()); 
humans.add(new Child()); 

foreach(Human hum in humans) { 
    hum.CleanTheRoom(); //I don't know the type of hum, but I don't care 
} 

Di que he estado recopilando instancias de humanos de varias ubicaciones; no sé de qué tipo es cada una. Pero todavía puedo iterar sobre ellos y llamar a CleanTheRoom(), porque comparten una clase principal.

Voy a agregar un ejemplo del mundo real. Digamos que tengo una clase Invoice con varias subclases para diferentes tipos de facturas; tal vez haya diferentes tipos de Invoice s para clientes de servicio en comparación con clientes que realizan compras únicas. A veces me preocupan las diferencias y solo trato con un tipo. Pero a veces quiero recorrer todas las facturas de este mes e imprimirlas. Si la clase principal tiene un método print() (que bien puede implementarse de manera diferente según los diferentes tipos), entonces puedo hacerlo.

+1

Esta es la mejor respuesta en mi opinión. El valor del polimorfismo se vuelve aparente cuando lo ve * siendo utilizado *, no cuando lo ve * definido *. – riwalk

+0

Desearía que hubiera un término breve para describir la herencia con polimorfismo. ¿Hay alguno? – Daisetsu

+1

El polimorfismo que se basa en las clases principales se denomina a veces "polimorfismo de subtipo" en ciencias de la computación. En el contexto de un lenguaje de programación orientado a objetos, nunca he visto la palabra "polimorfismo" utilizada para referirse a otra cosa que no sea el subtipo de polimorfismo (los genéricos también son una forma de polimorfismo, técnicamente, pero nunca nos referimos a ellos de esa manera) . Y yendo del otro lado, nunca he encontrado una forma de herencia que no permita el polimorfismo. Entonces, la palabra "polimorfismo" parece suficiente dentro de un contexto orientado a objetos. –

0

Sí, eso es correcto. Y puede llamar al método CleanTheRoom() sin saber qué "clase" de ser humano es.

Here tiene algunos ejemplos básicos.

0

Creo que no ves el beneficio, esa es la clave que te falta para comprender completamente el polimorfismo. Trataré de dar un ejemplo:

Digamos que tiene un formulario CRUD simple. Este es el código del botón de guardar:

var Client = PopulateDTO(); //put all the values in the controls, to an object 

if(Action==Actions.Create){ 
    _repository.Create(Client); 
} 
else if(Action==Actions.Update){ 
    _repository.Update(Client); 
} 
else if(Action==Actions.Delete){ 
    _repository.Delete(Client); 
} 

this.Close(); 

Este código funciona, pero es mal código, y difícil de leer.Vamos a usar el polimorfismo (y el patrón de estrategia):

public abstract class BaseStrategy{ 
    abstract void Do(ClientDto Client); 
} 

public class CreateStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Save(Client); 
    } 
} 

public class UpdateStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Update(Client); 
    } 
} 

public class DeleteStrategy:BaseStrategy{ 
    public override void Do(ClientDto Client){ 
    _repo.Delete(Client); 
    } 
} 

Por lo tanto, tenemos una clase abstracta, y 3 implementaciones, cada uno haciendo algo con el objeto de cliente. Ahora, el código del botón de guardar en forma será:

BaseStrategy stg = GetCorrectStrategy(); 

var Client = PopulateDTO(); 

stg.Do(Client); 

this.close; 

Y el método GetCorrectStrategy() será una instancia de la implementación de la estrategia correcta, dependiendo de si el usuario está creando, editar o borrar el cliente.

Espero que esta respuesta te ayude. Pero si no te ayudó, sugiero que leas sobre el patrón de estrategia, es uno de los mejores usos del polimorfismo en mi opinión

0

Dado que varias personas ya han dado buenos ejemplos de polimorfismo, ofreceré una perspectiva diferente de realmente me ayudó a asimilarlo.

En la programación funcional, las funciones son los conceptos de primera clase en contraste con OOP donde los objetos son supremos.

El polimorfismo es OOP qué coincidencia de patrón es para FP. Aquí hay una función que usa la coincidencia de patrones (usando una sintaxis de estilo ML).

let f x = 
     match x with 
     | T -> //do stuff with a T to return some value 
     | S -> //do stuff with an S to return some value 
     | U -> //do stuff with a U to return some value 
     | V -> //do stuff with a V to return some value 

Así que cuando se utiliza la función f, puede pasar que un objeto de cualquier tipo T, S, U o V. En inflexible de tipos idiomas FP como F #, el tipo de x se denota T|S|U|V. Dichos tipos se conocen comúnmente como tipos Sum o Uniones Etiquetadas.

Si arreglamos su ejemplo para hacer Human una clase abstracta, entonces quedará claro que el polimorfismo en OOP simplemente le da una forma de expresar un tipo de suma. Por ejemplo, CleanTheRoom es una función que toma un tipo Human. Pero Human es solo el nombre para el tipo Man|Woman|Child que es un tipo de suma. La gran diferencia entre los lenguajes como C# y los lenguajes funcionales como F # es que uno trata a los objetos como cosas de nivel superior mientras que el otro trata las funciones como cosas de nivel superior. Además, todo en los lenguajes de OOP como C# debe tener nombres. En un lenguaje funcional podríamos denotar el tipo Man|Woman|Child sin tener que nombrarlo explícitamente.

La clave no es pensar en el código como tener diferentes métodos CleanTheRoom, sino más bien pensar en CleanTheRoom como un método que toma un tipo Man|Woman|Child (que lleva el nombre Human). El polimorfismo es solo el detalle de implementación.

En resumen, el polimorfismo (especialmente con clases abstractas) básicamente solo le da una manera de nombrar tipos de suma y hacer coincidencia de patrones.

Ver:

0

Un ejemplo en C#:

Este es mi archivo de clase

class parent 
    { 
     public virtual string saySomething(string s) 
     { 
      return s+":Parent"; 
     } 
    } 
    class man : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Man"; 
     } 
    } 
    class woman : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Woman"; 
     } 
    } 
    class child : parent 
    { 
     public override string saySomething(string s) 
     { 
      return s+":Child"; 
     } 
    } 

Crea cuatro botones y una etiqueta.

Aquí es la implementación de un simple formulario1

private void Form1_Load(object sender, EventArgs e) 
     { 
      p1= new parent();  

     } 

     private void button1_Click(object sender, EventArgs e) 
     {    
      label1.Text = p1.saySomething("I am parent!"); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      p1 = new man(); 
      label1.Text = p1.saySomething("I am man!"); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      p1 = new woman(); 
      label1.Text = p1.saySomething("I am woman!"); 
     } 

     private void button4_Click(object sender, EventArgs e) 
     { 
      p1 = new child(); 
      label1.Text = p1.saySomething("I am child!"); 
     } 

Es tiempo de ejecución polimorfismo? P1 es un objeto. Dependiendo de la situación (Contexto), un clic de botón, está ejecutando diferentes partes del código. Por lo tanto, p1 se comporta de manera diferente según el evento click.

+0

Si observa este ejemplo, es polimorfismo. Pero este ejemplo realmente no muestra el poder del polimorfismo. –

0
class Program 
{ 
    static void Main(string[] args) 
    { 
     List<ICleanTheRoom> cleanerList = new List<ICleanTheRoom> 
      { 
       new Child(), 
       new Woman(), 
       new Man() 
      }; 
     foreach (var cleaner in cleanerList) 
     { 
      cleaner.CleanTheRoom(); 
     } 
    } 
} 

internal interface ICleanTheRoom 
{ 
    void CleanTheRoom(); 
} 

// No need for super type 

//class Human : ICleanTheRoom 
//{ 
// public virtual void CleanTheRoom() 
// { 
// } 
//} 


internal class Woman : ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Man: ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Child: ICleanTheRoom 
{ 
    public void CleanTheRoom() 
    { 
     throw new NotImplementedException(); 
    } 
} 
Cuestiones relacionadas