44

Is it OK to derive an abstract class from a non-abstract class or is there something wrong with this approach?

Here´s a little example:

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
}

In the example above I do not want to make the class Task abstract, because I want to instantiate it directly. PeriodicalTask should inherit the functionality from Task and add some additional members but I do not want to instantiate it directly. Only derived class of PeriodicalTask should be instantiated.

Jehof
  • 34,674
  • 10
  • 123
  • 155

4 Answers4

60

I don't see anything wrong with this approach.

You might have some basic type that can be described in concrete terms. Now, just because an object of this type might be further classified according to some subtype, it does not follow that all such subtypes are just as concrete; they may in turn require further concretization, as it were.

Real-world example:

Person -- concrete (non-abstract)
Sibling: Person -- abstract
Brother: Sibling -- concrete
Sister: Sibling -- concrete

Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • 1
    You can also override a concrete (yet virtual) method with an `abstract` one. Example `public abstract override string ToString();` overrides the concrete `ToString()` from `System.Object` with an `abstract` one. This forces all derived classes to supply a new implementation. – Jeppe Stig Nielsen Mar 11 '17 at 19:25
18

Nothing wrong with it.

If you look at a big hierarchy like WinForms, you will find several layers of abstract types.

MSBuild tasks are also a good (and more relevant) example.

leppie
  • 115,091
  • 17
  • 196
  • 297
16

This sort of thing happens all the time: All abstract classes inherit from System.Object, a class that is not abstract by itself.

new System.Object() is sometimes useful for locking, if you don't have anything else around, you could lock over.

Christian Klauser
  • 4,416
  • 3
  • 31
  • 42
  • 1
    Its a good point. This fact i missed, cause the inheritance from System.Object must not be set explicit. – Jehof Apr 09 '10 at 06:09
0

Using abstract is not the right approach here then, use a protected or internal constructor, for example. That would prevent instances of PeriodicalTask to be created directly, but its derived classes would still have access to it.

kprobst
  • 16,165
  • 5
  • 32
  • 53
  • Could you elaborate? Yes, a protected/internal constructor could prevent instances of `PeriodicalTask` from being directed created. But it would also require anything abstract methods/properties from `Task` to have implementations. – Matthew Whited Apr 08 '10 at 19:22
  • Never mind... I missed that Task was not abstract. Both approaches would work just as good in this situation. Other then you could not force someone to implement a method in a derived class. – Matthew Whited Apr 08 '10 at 19:26
  • @kprobst: Yes i can do it, but then i lose the possibility to define abstract members, that have to be implemented by derived types. Virtual members are no option, cause the derived types must define how they work – Jehof Apr 09 '10 at 06:05