2010-03-16 17 views
6

¿Alguien aquí tiene opiniones sobre cuándo usar la herencia y cuándo usar un identificador? ejemploHerencia o identificador

Herencia:

class Animal 
{ 
    public int Name { get; set; } 
} 

class Dog : Animal {} 

class Cat : Animal {} 

ejemplo Identificador:

class Animal 
{ 
    public int Name { get; set; } 

    public AnimalType { get; set; } 
} 

¿En qué situaciones debe prefiero qué solución y cuáles son los pros y los contras de ellos?

/Lina

+1

http://stackoverflow.com/questions/269496/inheritance-vs-aggregation –

+0

@jleedev: Esto no es una agregación o composición. Al menos no en un sentido estricto –

+0

Hmm, debería disminuir la velocidad. –

Respuesta

2

me gustaría utilizar la herencia, si las clases Herencia de (gato y perro en su ejemplo) tienen una interfaz diferente (métodos o campos), o si se utilizan para seleccionar un comportamiento diferente. Por ejemplo, en un proyecto real, tengo una clase base para generar código HTML. Dependiendo de la situación, creo la subclase correcta, que genera el HTML correcto. Estas clases tienen (principalmente) la misma interfaz, pero su comportamiento es muy diferente, no quiero seleccionarlo a través de if o cambiar.

6

Depende del tipo de acciones que necesita realizar en su sistema. Por ejemplo, si tiene algún tipo de acción común que debe hacerse en la forma diferente para cada uno de los objetos que debiera utilizar la herencia, por ejemplo:

class Shape 
{ 
    public abstract void Draw(); 
} 

class Circle : Shape 
{ 
    public override void Draw() 
    { 
     /* Custom implementation for Circle. */ 
    } 
} 

class Box : Shape 
{ 
    public override void Draw() 
    { 
     /* Custom implementation for Box. */ 
    } 
} 

Por otro lado, si algún tipo de y el objeto que más se parece a su propiedad que debe utilizar lo que se denomina como "identificador":

enum Color 
{ 
    Red, 
    Green, 
    Blue 
} 

class Box 
{ 
    public Color BoxColor { get; set; } 
} 

puede utilizar la herencia aquí (pero no se ve tan bien): RedBox, BlueBox, etc. La diferencia es que todas las cajas (incluso con diferente color) se manejaría de la misma manera y su comportamiento será común.

1

Eche un vistazo a dónde utiliza el código y cómo lo usa. Encuentro que la herencia siempre se presta cuando tienes objetos distintos que tienen una buena oportunidad para el polimorfismo.

piensa que una solución de registro, la manera de conectarse log(string info) debe ser heredada a un objeto que es distinto de lo que lo haga, como la tala en el disco, ingrese a la red, pantalla, etc.)

que he encontrado un olor a código es upcasting, cuando tienes que regresar a la clase real para hacer algo. Si estás haciendo eso, entonces probablemente no lo has usado apropiadamente.

La herencia es solo una herramienta, no la use porque puede, úsela porque le ayudará a escribir un código más claro que funcione de manera más eficiente.

1

Herencia es, en mi opinión, preferible cuando el comportamiento debe cambiar de acuerdo con el identificador dado. Como ejemplo, si simplemente desea proporcionar su Animal un método walk(), no tiene que proporcionar subclases (como perros y gatos parece, desde lejos, caminar del mismo modo).

Sin embargo, si queremos que tengan alguna makeNoise(Mood mood) método, la herencia será útil:

class Cat { 
    public void makeNoise(Mood mood) { 
     swithch(mood) { 
      case happy: 
       purr(); 
       break; 
       // and so on 
4

Lo que se llama un "identificador" yo llamaría un enfoque de enumeración.

El uso de una enumeración para subdividir solo es adecuada para distinguir un conjunto pequeño y fijo de posibilidades. Cuando lo exageres, verás que las declaraciones de cambio aparecen en todas partes en tu código y que es un fuerte indicador de que debes usar la herencia en su lugar.

0

Eso es faily simple, los dos vienen a resolver dos problemas diffrent, Cuando haya Diffrent comportamientos, se debe utilizar la herencia, por ejemplo, si la clase de animal tiene un comportamiento de "hablar" debe ser implementado utilizando polimorfismo y herencia.

3
  • Si la única diferencia entre los animales es su tipo, utilice la propiedad AnimalType.

  • Si diferentes animales tienen diferentes implementaciones de propiedades y métodos o métodos adicionales, cree clases que se derivan de Animal.

    Si la comprobación del tipo de animal es un caso de uso común, considere proporcionar también una propiedad AnimalType, como alternativa a los lotes is/as.

1

Cuando voy de general a especializado, me gustaría ir con la herencia. De esa manera (en relación con su ejemplo), solo tendrá que hacer los métodos de caminar, comer, dormir, etc. una vez. Sin embargo, si están en el mismo nivel, sería mejor simplemente usar el identificador. Por ejemplo. No querría basar un gato en un perro, porque entonces tendría que deshabilitar opciones además de agregar nuevas.

2

La herencia unirá estrechamente el comportamiento del gato y el perro con el de un animal. Que puede ser lo que quieres

Sin embargo, si usted está tratando de crear un universo donde todo es posible, y un animal puede cambiar su tipo, es posible que prefiera utilizar el enfoque identificador ..

Pero se puede ir más lejos.

De acuerdo con la Gang of Fours design patterns que debiera

"favor 'composición de objetos' sobre la 'herencia de clases'."

Un animal es solo un perro porque tiene una cola que se menea y ladra. En tu universo, donde con el tiempo un perro podría aprender a hablar, querrás poder modificar este comportamiento.

Puede intentar abstraer su comportamiento y, a continuación, dentro de este comportamiento, puede usar la herencia.

Con esta estructura de clases:

class Tail 
{ 
    DoYourThing() 
} 

class WaggyTail : Tail 
{ 
    DoYourThing() 
    { 
    // Wag 
    } 
} 

class Noise 
{ 
    DoYourThing() 
} 

class Bark : Noise 
{ 
    DoYourThing() 
    { 
    // Bark 
    } 
} 

class Talk : Noise 
{ 
    DoYourThing() 
    { 
    // Talk 
    } 
} 

class Animal 
{ 
    public Noise { get; set; } 
    public Tail { get; set; } 
} 

Puede configurar sus gatos y perros:

Animal dog = new Animal { Noise = new Bark(), tail = new DoggyTail() } 
    Animal cat = new Animal{ Noise = new Purr(), tail = new CattyTail() } 

.. entonces cuando se necesita su súper raza que usted puede cambiar su comportamiento sencillo

perro.Ruido = nuevo Talk();

.. Oye, presto, tu perro puede hablar ... Si necesitas que tu perro cante, simplemente creas una nueva clase de Sing ... no se necesitan más cambios.

0

Ok, mi nueva regla general será ir por la herencia si las clases tienen comportamientos diferentes, de lo contrario buscaré un identificador de algún tipo. (Por supuesto, la decisión final dependerá del entorno en el que se utilizarán las clases). ¡Gracias por todas tus respuestas!

Cuestiones relacionadas