2010-04-08 22 views
32

È corretto derivare una classe astratta da una classe non astratta o c'è qualcosa di sbagliato in questo approccio?Derive classe astratta da classe non astratta

Here's un piccolo esempio:

public class Task { 
    // Some Members 
} 

public abstract class PeriodicalTask : Task { 
    // Represents a base class for task that has to be done periodicaly. 
    // Some additional Members 
} 

public class DailyTask : PeriodicalTask { 
    // Represents a Task that has to be done daily. 
    // Some additional Members 
} 

public class WeeklyTask : PeriodicalTask { 
    // Represents a Task that has to be done weekly. 
    // Some additional Members 
} 

Nell'esempio di cui sopra non voglio fare l'astratto classe Task, perché voglio istanziare direttamente. PeriodicalTask ​​dovrebbe ereditare la funzionalità da Task e aggiungere alcuni membri aggiuntivi, ma non voglio istanziarlo direttamente. Solo la classe derivata di PeriodicalTask ​​deve essere istanziata.

risposta

49

Non vedo nulla di sbagliato in questo approccio.

Si potrebbe avere un tipo di base che può essere descritto in termini concreti. Ora, solo perché un oggetto di questo tipo potrebbe essere ulteriormente classificato secondo alcuni sottotipi, non ne consegue che tutti questi sottotipi siano altrettanto concreti; possono a loro volta richiedere ulteriore concretizzazione, per così dire.

mondo reale esempio:

Person - concreta (non astratta)
Sibling: Person - astratto
Brother: Sibling - concreta
Sister: Sibling - concreta

+2

Esempio perfetto Dan –

+0

Un buon esempio pertanto accettato – Jehof

+0

Wow! Davvero, bel esempio. – ManuelSchneid3r

0

L'utilizzo dell'estratto non è l'approccio giusto qui, quindi utilizzare un costruttore protetto o interno, ad esempio. Ciò impedirebbe alle istanze di PeriodicalTask ​​di essere create direttamente, ma le sue classi derivate avrebbero comunque accesso ad essa.

+0

Potresti elaborare? Sì, un costruttore protetto/interno potrebbe impedire che le istanze di "PeriodicalTask" vengano create direttamente. Ma richiederebbe anche qualsiasi metodo/proprietà astratti da 'Task' per avere implementazioni. –

+0

Non importa ... Mi mancava che il compito non fosse astratto. Entrambi gli approcci funzionerebbero altrettanto bene in questa situazione. Altrimenti non è possibile forzare qualcuno a implementare un metodo in una classe derivata. –

+0

@kprobst: Sì, lo posso fare, ma poi perdo la possibilità di definire membri astratti, che devono essere implementati dai tipi derivati. I membri virtuali non sono un'opzione, perché i tipi derivati ​​devono definire come funzionano – Jehof

17

Niente di male.

Se si osserva una grande gerarchia come WinForms, si troveranno diversi livelli di tipi astratti.

Le attività di MSBuild sono anche un buon esempio (e più pertinente).

12

Questo tipo di hing succede sempre: tutte le classi astratte ereditano da System.Object, una classe che non è abstract di per sé.

new System.Object() è talvolta utile per il blocco, se non si dispone di altro, è possibile bloccare.

+0

È un buon punto. Questo fatto mi è sfuggito, perché l'ereditarietà di System.Object non deve essere impostata esplicitamente. – Jehof