Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Base abstract generic class is a bad choice in most situations." Why? (Or Why not)

Tags:

I have just seen on the comment to a blog post:

Base abstract generic class is a bad choice in most situations

Is this true, if not why?

What insight(s) leads to this statement?

like image 306
Ian Ringrose Avatar asked Feb 18 '11 11:02

Ian Ringrose


People also ask

What is abstract base class and why we use it?

An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier ( = 0 ) in the declaration of a virtual member function in the class declaration.

Should base class always be abstract?

Yes, it is reasonable and beneficial to mark explicitly as abstract a base class that should not be instantiated -- even in the absence of abstract methods. It enforces the common guideline to make non-leaf classes abstract. It prevents other programmers from creating instances of the class.

Is abstract a generic class?

We can first declare an abstract class that uses generics T . Our generic T could refer to any class (i.e. String , Double , Integer , etc.). This is declared when the AbstractJob class is referenced. These generics can be named anything; it doesn't have to be T .

Can you inherit an abstract base class?

NO. Abstract methods(defintion) are overridden by base class' overriding methods.


2 Answers

I agree, because anything that inherits an abstract generic class will not be polymorphic with the base class. That is, if you have

abstract class myBase<T>

then you create

class myThing: myBase<thing> class myOtherThing: myBase<otherThing> 

you can't create methods that work against myThing and myOtherThing since they do not share an ancestor. There's no point in the base class being abstract, really, it might as well just be a class.

But if you have a base class

abstract class myBase class myBase<T>: myBase 

as is a common pattern for generic classes (like IEnumerable - using interfaces), then they all share myBase.

(edit) I just read the actual blog post - and actually, the comment is not really valid in that situation. The "abstract generic base class" he's referring to, Range<T> inherits IEnumerable<T> which inherits non-generic interface IEnumerable. So it's not really an "abstract generic base class." But generally I think it's true.

like image 120
Jamie Treworgy Avatar answered Sep 24 '22 00:09

Jamie Treworgy


"Most situations" is outrightly vague. A generic abstract class (or interface) is a bad idea if the only common ancestor between descendants of such class is System.Object (as noted by other commenters of this question).

Otherwise (as in, if you do have a meaningful common ancestor), it's a good idea if you want to "rename" or "specialize" members. Consider this example:

// Meaningful common ancestor for the working classes. interface IWorker {    object DoWork(); }  // Generic abstract base class for working classes implementations. abstract WorkerImpl<TResult> : IWorker {    public abstract TResult DoWork();     object IWorker.DoWork()    {       return DoWork(); // calls TResult DoWork();    } }  // Concrete working class, specialized to deal with decimals. class ComputationWorker : WorkerImpl<decimal> {     override decimal DoWork()     {        decimal res;         // Do lengthy stuff...         return res;     } } 

In this example, DoWork() was redefined in the abstract class, becoming concrete and specialized in ComputationWorker.

like image 21
Humberto Avatar answered Sep 24 '22 00:09

Humberto