views:

189

answers:

9

I guess the question title sums it up. Is there a time when it would be considered good design for an ABC to have data members? I have been wondering if there is a situation where this is OK. The only ones I can come up with all are static, and even then it's kind of a stretch.

A: 

I see this in plugin architectures, like Paint.NET's.

pyrochild
+4  A: 

I don't see why an ABC couldn't properly have per-instance (aka non-static) data members, as needed to support the methods it supplies to subclasses. Take the common case in which an ABC exists to supply a Template Method DP (the hook methods being abstract) -- if part of the function of the organizing method is to update some instance variables (for example, a count of how many times the method was called), then obviously those variables should also be supplied by the ABC. Can you explain better why you think that's bad design?!

Alex Martelli
Agreed. Data members in abstract classes save programmers from implementing them multiple times and provide a single type through which to access them ;)
Cecil Has a Name
After reading about template method pattern, I think this is a really good reason. I've read from many "big" c++ books that ABC's shouldn't have data, so I was wondering if there was an exception.
rlbond
A: 

Inversion of Control might require this. For example you have a bunch of classes that take an instance of Logger, the abstract class they're based off might have a constructor store it in an member variable or private property (assuming of course you remember to call the base constructor grin)

blowdart
+1  A: 

An abstract class can have whatever members it needs to support the functionality it supplies to the classes that inherit from it. That's not to say these would be directly accessible to the subclasses: they might be read and changed only through method calls made by the subclasses or their clients.

Curt Sampson
A: 

It is OK, when your data member in your abstract class contains base code for inheriting classes

I would think about using an interface, when the data member is just to describe your class

Peter Gfader
A: 

Yes, its possible to provide member variables in an abstract base class with the intention that its subclasses will use those members to make a concrete implementation.

Here's a concrete example, using a car analogy that we've all come to love.

Let's say we make Car an abstract base class, which has placeholders for wheels, chassis, and an engine for its its subclasses to use:

abstract class Car {
    Wheels wheels
    Chassis chassis
    Engine engine

    abstract void accelerate();
    abstract void decelerate();
}

Now, for a class that extends Car, the members are already there to use, so the responsibility of a subclass is to populate those member variables:

class NiceCar extends Car {
    Decoration decoration;

    public NiceCar() {
        wheels = new ChromeWheels();
        chassis = new LightweightCompositeChassis();
        engine = new LotsOfHorsepowerEngine();
        decoration = new CoolRacingStripes();
    }

    void accelerate() {
        engine.feedFuel();
    }

    void decelerate() {
        wheels.applyBrakes();
    }
}

As can be seen, the abstract base class can work as a blueprint for which components (member variables) should be filled in to get a full functionality of a class. In this case, the Car provides basic parts of a car to be used in a concrete implementation. NiceCar uses those member fields and adds some for its own features, such as a decorative paint job.

coobird
A: 

I suspect that you are drawing too tight a circle around your concept of an abstract base class.

An abstract base class (as opposed to a pure interface) is a class that intends for some of its functionality to be used by child classes. It will thus have some functionality along with methods that are intended to be over-ridden (the interface part). There is no reason why this functionality should not have member variables associated with it.

Many frameworks are based off of inheritance. These will almost inevitably have abstract classes with member variables. For instance, DirectShow is the multimedia streaming framework in Windows. The sources, encoders, decoders, etc. are all implemented in what are called "filters". There are base classes for various types of filters. Each of them will have member variables for the upstream and downstream filters, the negotiated media types, etc.

Steve Rowe
A: 

If it's a state used by all inherited classes, I think it's mandatory to move it to the base class. Even though the base is abstract. I think most people that are into refactoring would agree with me on this.

There might be several reasons why some state should be in the base. Reducing code duplication is a good reason enough.

Cheers !

Edit: Please tell me why you down vote, so I can improve. Thanks!

Magnus Skog
+1 to compensate the downvote. If state is common to all derived classes, then by all means move it up to the base class.
Dan C.
Thanks Dan. That downvote was just mindboggling :)
Magnus Skog
A: 

As others have mentioned one adds instance fields to any sort of class when one needs to store state. This holds true of abstract or concrete classes - there is no difference.

Why should it make difference ? After all an abstract class is just like anyclass except it can't be instsntiated, requiring subclassing etc to complete the class.

mP