views:

265

answers:

6

An abstract base class (interface class) usually has all its member functions abstract. However, I have several cases where member functions consisting of calls to the abstract methods of the interface are used. I can implement them in a derived-but-still-abstract class, or I can implemented the methods as non-abstract, non-virtual methods of the interface class.

Are there any problems design-wise with implementing the methods in the interface class? Is it bad style, and if so, why?

Does the same hold for static methods?

For example

class IFoo
{
    public:
    virtual ~IFoo();
    virtual double calcThis( InputType p ) const = 0;
    virtual double calcThat( InputType p ) const = 0;
    double calcFraction( InputType p ) { return calcThis( p ) / calcThat( p ); }
    static BarType bar( InputType p );
};

class MyFoo : public IFoo
{
    public:
    // implements IFoo
    virtual double calcThis( InputType p ) const;
    // implements IFoo
    virtual double calcThat( InputType p ) const;
};

versus

class IFoo
{
    public:
    virtual ~IFoo();
    virtual double calcThis( InputType p ) const = 0;
    virtual double calcThat( InputType p ) const = 0;
};

class FooBase : public IFoo
{
    public:
    virtual ~FooBase();
    double calcFraction( InputType p ) { return calcThis( p ) / calcThat( p ); }
    static BarType bar( InputType p );
};

class MyFoo : public FooBase
{
    public:
    // implements IFoo
    virtual double calcThis( InputType p ) const;
    // implements IFoo
    virtual double calcThat( InputType p ) const;
};
A: 

Yes. It is perfectly fine and often desireable to implement methods (virtual or non-virtual) in an abstract base class. If you really want an interface, it is probably best to use your second construction so the use is clear to the reader, but both are perfectly legal C++. I just wouldn't use the 'I' designator if there was implementation present.

Steve Rowe
+8  A: 

Absolutely. This is how the template method pattern works (although that's not necessarily implementing an interface) - it's perfectly acceptable, and quite often a good idea.

The Java AbstractList class is a good example of this.

EDIT: Sorry not to have replied before. Your calcFraction method looks to me like it's an implementation of the template method pattern - it's a concrete implementation based on calling abstract methods.

Now I would agree with DrPizza - if you're calling something an interface, it really shouldn't have any implementation. It okay for an abstract base class to have non-abstract methods (as per your question title) but I don't consider "abstract base class" and "interface class" to be equivalent. This could potentially be my C# and Java background, where you can declare the type as an interface - but then can't provide any implementation.

Jon Skeet
Interesting point, but template method (or strategy pattern, or non-virtual interface) is rather the other way around isn't it? That would be an implementation-oriented class, most probably with data members and all, which delegates some of its implementation to derived classes.
andreas buykx
Indeed, concrete functions in abstract bases are perfectly fine. I'm thinking about sutter's article in this case: http://www.gotw.ca/publications/mill18.htm
Johannes Schaub - litb
+1  A: 

Yes absolutely. This is one of the reasons for having an abstract class as opposed to an interface.

Paddy
A: 

I don't see a reason not to have some implementation in an abstract class.

Gilad Naor
+1  A: 

I always thought that's what abstract classes are actually for: implement some basic behaviour common to all descendants, but make the parts abstract that are specific for a derived class.

Thorsten Dittmar
+2  A: 

If you're calling it an interface (i.e. which you seem to be by your use of the naming convention "IFoo") then it should be a pure interface (no implementations).

If it's merely an abstract class then a mix of pure virtual and implemented methods is perfectly reasonable.

DrPizza
Could you be more specific/detailed on why I should leave it a pure interface? Is it merely convention or are there other penalties?
andreas buykx
By convention, something labelled as an interface is "pure". There are some situations where I suspect your interfaces _must_ be pure, such as COM, but if you're just writing C++ it's really up to you. When writing an interface, is there common functionality that will be useful to every implementer? If so, then make it an abstract class. If not--if every implementation is going to be substantially different--go for a pure interface.
DrPizza
Just remember this is purely a question of what you call it: "interface" normally just means "an abstract class with no function implementations". One option is to split your class into one base class with only pure virtual functions (which you call "the interface"), and another which derives from that and implements some of them (which you call "a mixin"). The role of the mixin is to allow the concrete class to only implement a small number of functions. But you could also permit concrete classes to do all the work themselves, and not derive from the mixin at all.
Steve Jessop
... That's because inheriting from an abstract class and then overriding all the non-pure functions as well as the pure ones, is at best pointless, and at worst might mislead someone or result in errors if someone assumes that all implementations of a function will have some particular performance characteristic which the base class implementation happens to have.
Steve Jessop