2009-06-09 10 views
5

Se ho una classe astratta e classi derivate di quella classe, correggo che, secondo la buona pratica pratica di progettazione, le classi derivate non dovrebbero fornire metodi extra pubblici (dovrebbero solo implementare classi astratte ed eventualmente sovrascrivere i metodi principali))?Metodi pubblici extra nelle classi derivate?

Inoltre, è prassi accettabile avere una firma di metodo del costruttore diversa per ciascuna classe derivata?

+0

* EDIT * FYI, mi riferisco al caso in cui stai costruendo un oggetto da una fabbrica. Sto sostenendo che il codice chiamante, nel caso di una fabbrica, dovrebbe sapere quali metodi aspettarsi di avere dalle classi derivate. –

risposta

5

Personalmente, non vedo alcun problema con entrambi.

Per quanto riguarda i metodi pubblici in più su classi derivate:

C'è scarsa utilità in questo, in molti casi. I metodi extra non saranno utilizzabili quando la classe è stata lanciata o impostata su un riferimento alla classe base, il che limita fortemente l'utilità di questa pratica. Detto questo, non c'è nulla di particolarmente sbagliato in questo approccio. Le sottoclassi hanno lo scopo di aggiungere un comportamento specifico - a volte, in una gerarchia di classi, c'è un nuovo comportamento in una sottoclasse che non è appropriato per la classe base. Se la sottoclasse verrà utilizzata frequentemente da sola, sembra perfettamente ragionevole che il comportamento extra venga modellato nei metodi.

Per quanto riguarda le firme costruttore -

non vedo alcun problema con questa operazione. Le sottoclassi spesso richiedono più informazioni per essere messe in uno stato utilizzabile rispetto alla classe astratta. Detto questo, in genere mi assicuro di implementare ogni costruttore nella classe base, oltre a aggiungere i nuovi parametri richiesti per la sottoclasse.

Detto questo:

A meno che non ci sono buone ragioni, mi piacerebbe evitare di avere un costruttore della sottoclasse con un minor numero di parametri rispetto alla classe di base ... perché dovrei essere in grado di specificare qualcosa su un caso più generico e non il caso specifico? Trovo che di solito si confonda quando le sottoclassi hanno opzioni di costruzione completamente diverse rispetto alle loro classi base.

+0

se stai costruendo un oggetto da una fabbrica, ad esempio, allora ho ragione che non ci dovrebbero essere metodi extra pubblici? Non dovrebbe il codice chiamante, nel caso di una fabbrica, sapere quali metodi aspettarsi di avere? –

+0

Dipende - anche se si sta costruendo da una fabbrica, la fabbrica dovrà conoscere il tipo di tempo di compilazione dell'oggetto (per chiamare il costruttore appropriato). Può "sapere" sui parametri extra. In questo caso, però, dipende solo dallo scenario, da come verrà utilizzato, ecc. –

1

È perfettamente possibile aggiungere ulteriori metodi pubblici alle classi derivate. È anche perfettamente accettabile dare loro diversi contrasti. (In realtà, questo è abbastanza comune.)

0

le classi derivate non dovrebbero fornire metodi pubblici aggiuntivi

Può un cane fare cose che un animale non può?

Inoltre, è prassi accettabile avere una firma del metodo del costruttore diversa per ciascuna classe derivata?

Non c'è nessun problema qui. I tipi derivati ​​non sono richiesti per corrispondere alle firme del costruttore dei loro fratelli o genitori.

+0

Per rispondere alla tua domanda, Sì Un cane PU CAN fare cose che alcuni animali non possono fare ... Come abbaiare, mordere, correre, tosare, saltare, ecc ... I vermi sono animali, (non sono piante) - e un worm non può fare nessuna di queste cose ... –

2

Questa è la bellezza delle classi derivate.

Mentre una classe Pen può avere una funzione write(), una classe RetractablePen che estende Pen potrebbe anche avere una funzione retraPoint().

Quando estendi una classe significa - letteralmente - estendendone la funzionalità.

+0

Se stai costruendo un oggetto da una fabbrica, ad esempio, allora ho ragione che non ci dovrebbero essere metodi extra pubblici ? Non dovrebbe il codice chiamante, nel caso di una fabbrica, sapere quali metodi aspettarsi di avere? –

+0

Se lo stai costruendo da una fabbrica, probabilmente stai usando il polimorfismo e guardi la classe come se fosse solo la sua genitrice. In tal caso, non avresti accesso ai metodi definiti nella classe child a meno che tu non abbia controllato per l'istanza e lo abbia lanciato. –

1

No, è perfettamente ragionevole (e talvolta molto necessario in base alla progettazione) aggiungere ulteriori metodi pubblici. Considerare la situazione (completamente inventata) di una classe di base astratta Shape con un membro Location e un metodo Size. Ad esempio, se si deriva Polygon da Shape, è possibile aggiungere un metodo pubblico denominato GetNumberOfSides(), ad esempio; ma non vuoi averlo quando si ottiene Circle da Shape.

Allo stesso modo, i tipi derivati ​​possono presentare requisiti di costruzione molto diversi; non è davvero possibile sapere quali potrebbero essere tutti i requisiti quando si definisce la classe base astratta, quindi sentirsi liberi di avere firme diverse. Solo perché i tuoi tipi derviati saranno polimorfici rispetto alla classe base astratta non significa che quella classe base impone limiti rigorosi su come è possibile implementare le astrazioni definite in quella classe base; sei libero di farlo praticamente come vuoi tu.

2

Va bene in generale.

Ciò che si desidera evitare è l'utilizzo dello specifico nel generico. Ad esempio

foreach(Animal a in myFarm.Animals) 
{ 
    a.Feed(); 
    // this is a bit grim 
    if(a is Horse) 
    { 
     ((Horse)a).CleanStable(); 
    } 
} 

Quindi non è l'atto di aggiungere il metodo pubblico ma piuttosto da dove vengono chiamati.

+0

Voglio un cavallo che pulisca la propria stalla! Dove posso prenderne uno? ;) –

+0

Sì ... lo so ... scrivo durante i tempi di costruzione, quindi non ho tempo di essere pedante come di solito sono ...: (... lo farà. – Quibblesome

0

Non è solo accettabile, è spesso necessario che i costruttori siano diversi. Per esempio, se abbiamo un (immutabile) Classe Rectangle ed estenderlo con un (immutabile) Square, il costruttore di Piazza dovrebbe essere (per usare Java per il momento)

public Square(double size) 

mentre il costruttore di Rectangle sarebbe

Ciò che deve succedere è che il costruttore della sottoclasse chiami un costruttore di superclasse appropriato.

Come per i metodi pubblici, può dipendere dall'uso. Per il caso Square, non aggiungerei altri metodi. In Java, tuttavia, esiste una sottoclasse PrintWriter di Writer il cui scopo è aggiungere alcuni metodi di convenienza. In questo caso, penso che vada bene (Java ha certamente alcuni esempi negativi ma non penso che questo sia uno di questi). Mi aspetto anche la possibilità di alcuni metodi aggiuntivi per i tipi di container/sottoparte.

Quello che non dovresti fare è cambiare i metodi delle super classi in modo tale da violare le aspettative della super classe.

Problemi correlati