Question

If you have several classes where you want them to inherit from a base class for common functionality, should you implement the base class using a class or an abstract class?

Was it helpful?

Solution

That depends, if you never want to be able to instantiate the base class then make it abstract. Otherwise leave it as a normal class.

OTHER TIPS

If the base class ought not to be instantiated then make it an abstract class - if the base class needs to be instantiated then don't make it abstract.

In this example it makes sense to make the base class abstract as the base class does not have any concrete meaning:

abstract class WritingImplement
{
    public abstract void Write();
}

class Pencil : WritingImplement
{
    public override void Write() { }
}

However in this next example you can see how the base class does have concrete meaning:

class Dog
{
    public virtual void Bark() { }
}

class GoldenRetriever : Dog
{
    public override void Bark() { }
}

It is all pretty subjective really - you ought to be able to make a pretty good judgment call based on the needs of your particular domain.

It depends, does it make sense for the base class in question to exist on it's own without being derived from? If the answer is yes, then it should be a regular class, otherwise, it should be an abstract class.

I suggest:

  • Make an interface.
  • Implement the interface in your base class.
  • Make the base class a real class, not abstract (see below for why).

The reason I prefer real classes instead of abstract classes is that abstract classes cannot be instantiated, which limits future options unnecessarily. For example, later on I may need the state and methods provided by the base class but cannot inherit and do not need to implement the interface; if the base class is abstract I am out of luck, but if the base class is a regular class then I can create an instance of the base class and hold it as a component of my other class, and delegate to the instance to reuse the state/methods provided.

Yes this does not happen often, but the point is: making the base class abstract prevents this kind of reuse/solution, when there is no reason to do so.

Now, if instantiating the base class would somehow be dangerous, then make it abstract - or preferably make it less dangerous, if possible ;-)

Think of it like a bank account:

You can make a generic abstract base account called "Account", this holds basic information such as customer details.

You can then create two derived classes called "SavingAccount" or "DebitAccount" which can have their own specific behaviour whilst benefiting from the base class behaviour.

This is a situation where the customer must have either a Savings Account or a Debit Account, a generic "Account" is not allowed as it is not very popular in the real world to have just an account of no description.

If you can create a similar scenario for your needs, abstract is the way to go.

Abstract classes are for partially implemented classes.

By itself doesn't make sense to have an instance of an abstract class, it needs to be derived. If you would like to be able to create the base class it cannot be abstract.

I like to think of abstract classes as interfaces which have some members pre-defined since they are common to all sub-classes.

Think of this a different way

Is my a base class a complete object on it's own?

If the answer is no, then make it abstract. If it's yes then you likely want to make it a concrete class.

I would say if you are not planning on calling the base class by itself, the then you should define it as an abstract class.

The depends on whether you want the base class to be implemented on its own or not.

As an abstract class, you can't make objects from it.

Abstract classes are great for predefined functionality, for example - when know the minimum exact behaviour a class should expose but not what data it should use to do it or the exact implementation.

abstract class ADataAccess
{
    abstract public void Save();
}

Normal (non abstract) classes can be great for similar things but you have to know the implementation specifics to be able to write them.

public class DataAccess
{
    public void Save()
    {
        if ( _is_new )
        {
            Insert();
        }
        else if ( _is_modified )
        {
            Update();
        }
    }
}

Also, you could use interfaces (individually or on classes, whether abstract or not) to define the same sort of prototype definition.

interface ISaveable
{
    void Save();
    void Insert();
    void Update();
}

class UserAccount : ISavable
{
    void ISavable.Save() { ... }
    void ISavable.Insert() { ... }
    void ISavable.Update() { ... }
}

Yet another option may be using generics

class GenDataAccess<T>
{
    public void Save()
    {
        ...
    }
}

All these methods can be used to define a certain prototype for classes to work with. Ways to make sure that code A can talk to code B. And of course you can mix and match all of the above to your liking. There is no definite right way but I like defining interfaces and abstract classes, then referring to the interfaces. That way eliminates some of the thought requirements for "plumbing" in higher level classes while keeping the maximum flexibility. (having interfaces takes away the requirement of using the abstract base class, but leaves it as an option).

I think a lot of you should resit basic OO classes again.

The basic underlying principle in OOA/OOD is to abstract abstract abstract, until you can't abstract no more. If what your looking at is an abstraction then so be it, thats what your OOA/OOD already told you. However if you sitting there wondering whether "code" should be abstract or not then you obviously don't know what the term means and should go learn basic OOA/OOD/OOP again :-)

More to the point you should learn Design Patterns and Harmonic Theory, this will help with your OO designs immensely!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top