2010-03-16 14 views
6

Qualcuno qui ha opinioni su quando ereditare l'utente e quando utilizzare un identificatore? EsempioEreditarietà o identificatore

Ereditarietà:

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

class Dog : Animal {} 

class Cat : Animal {} 

Identifier esempio:

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

    public AnimalType { get; set; } 
} 

In quali situazioni dovrebbe preferisco che la soluzione e quali sono i pro ei contro di loro?

/Lina

+1

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

+0

@jleedev: non è un'aggregazione o una composizione. Almeno non in senso stretto. –

+0

Hmm, dovrei rallentare. –

risposta

2

userei eredità, se le classi che ereditano (gatto e cane nel tuo esempio) hanno una diversa interfaccia (metodi o campi), o se essi sono utilizzati per selezionare un comportamento diverso. Ad esempio, in un progetto reale ho una classe base per generare codice HTML. A seconda della situazione, creo la sottoclasse corretta, che genera il codice HTML corretto. Queste classi hanno (per lo più) la stessa interfaccia, ma il loro comportamento è così diverso, che non voglio selezionarlo tramite if o switch.

6

Dipende dal tipo di azioni che è necessario eseguire nel sistema. Per esempio, se si dispone di una certa azione comune che dovrebbe essere fatto in modo diverso per ognuno dei vostri oggetti di quanto deve utilizzare l'ereditarietà, ad esempio:

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. */ 
    } 
} 

D'altra parte, se un certo tipo di e oggetto di più appare come il suo proprietà che si dovrebbe usare ciò che si chiama come "identificatore":

enum Color 
{ 
    Red, 
    Green, 
    Blue 
} 

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

è possibile utilizzare l'ereditarietà qui (ma non sembra così buono): RedBox, BlueBox, ecc La differenza è che tutte le caselle (anche quelli con colori diversi) sarebbe gestito allo stesso modo e il loro comportamento sarà comune.

1

Dai un'occhiata a dove usi il codice e come lo usi. Trovo che l'eredità si presta sempre quando si hanno oggetti distinti che hanno una buona opportunità per il polimorfismo.

Pensate una soluzione di registrazione, il modo per accedere log(string info) deve essere ereditata da un oggetto che è distinto in ciò che il suo fare, come ad esempio la registrazione su disco, accedere alla rete, schermo, ecc)

ho trovato un odore del codice è in aumento, quando devi tornare alla classe reale per fare qualcosa. Se lo fai, probabilmente non lo hai usato in modo appropriato.

L'ereditarietà è solo uno strumento, non usarlo perché è possibile, usarlo perché ti aiuterà a scrivere codice più chiaro che funziona in modo più efficiente.

1

L'ereditarietà è, a mio avviso, preferibile quando il comportamento deve cambiare in base all'identificatore indicato. Ad esempio, se si desidera semplicemente fornire il proprio Animal un metodo walk(), non è necessario fornire sottoclassi (poiché cani e gatti sembrano, da lontano, camminare allo stesso modo).

Tuttavia, se si desidera loro di avere qualche metodo makeNoise(Mood mood), eredità sarà utile:

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

Che si chiama un "identificatore" che chiamerei un approccio enum.

L'utilizzo di un'enumerazione per suddividere la divisione è adatto solo per distinguere un insieme limitato di possibilità. Quando lo esagerate, vedrete le istruzioni switch che appaiono ovunque nel vostro codice e questo è un indicatore forte che dovreste usare invece dell'ereditarietà.

0

Quello faily semplice, i due vengono a risolvere due problemi diffrent, Dopo aver Diffrent comportamenti, si dovrebbe utilizzare l'ereditarietà, per esempio, se la classe animale ha un comportamento di "parlare" dovrebbe essere implementato utilizzando polimorfismo ed ereditarietà.

3
  • Se l'unica differenza tra gli animali è il loro tipo, utilizzare la proprietà AnimalType.

  • Se diversi animali hanno diverse implementazioni di proprietà e metodi o altri, creare classi che derivano da Animal.

    Se la verifica per il tipo di animale è un caso d'uso comune, valutare la possibilità di una proprietà AnimalType così, in alternativa a un sacco di is/as.

1

Quando si passa da generale a specializzato, direi passare all'eredità. In questo modo (in relazione al tuo esempio) dovresti solo fare i metodi di passeggiata, mangiare, dormire, ecc. Una volta. Se sono sullo stesso livello, tuttavia, sarebbe meglio usare semplicemente l'identificatore. Per esempio. Non si vorrebbe far uscire un gatto da un cane, perché in tal caso si dovrebbero disabilitare le opzioni oltre ad aggiungerne di nuove.

2

L'ereditarietà accoppierà strettamente il comportamento del gatto e del cane a quello di un animale. Quale potrebbe essere quello che vuoi.

Tuttavia, se si sta cercando di creare un universo in cui tutto è possibile, e un animale possibile modificarne il tipo, si può scegliere di utilizzare l'approccio identificativo ..

Ma si può prendere questo ulteriore.

Secondo il Gang of Fours design patterns si dovrebbe

"Favor 'la composizione di oggetti' over 'ereditarietà delle classi'."

Un animale è solo un cane perché ha una coda che agita e abbaia. Nel tuo universo, dove nel tempo un cane potrebbe imparare a parlare, vorrai essere in grado di modificare questo comportamento.

Si potrebbe quindi provare a astrarre il proprio comportamento e quindi all'interno di questo comportamento è possibile utilizzare l'ereditarietà.

Con questa struttura di classe:

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; } 
} 

È possibile impostare i vostri cani e gatti:

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

.. poi quando si ha bisogno la vostra super-razza che possibile semplice cambiare il loro comportamento

cane.Noise = new Talk();

.. Ehi, presto il tuo cane può parlare .. Se hai bisogno del tuo cane per cantare, devi solo creare una nuova classe di canto .. non sono necessari ulteriori cambiamenti.

0

Ok, la mia nuova regola empirica sarà quella di andare per ereditarietà se le classi hanno comportamenti diffrenti, altrimenti vado a cercare un identificatore di qualche tipo. (Ovviamente la decisione finale dipenderà dall'ambiente in cui le classi dovranno essere utilizzate). Grazie per tutte le vostre risposte!