Why Can't I Use Inheritance to Implement an Interface in C++

Why can't I use inheritance to implement an interface in C++?

struct B is implementing a function that happens to be called foo and takes no arguments. That function has obviously absolutely no relation to A::foo. So when struct C derives from both A and B, it ends up having inherited:

  • the responsibility to provide an implementation for A::foo
  • a method B::foo that has the same name and signature as A::foo, but is not related to it in any way

I think the problem is obvious. You are trying to use A as the equivalent of a C# interface, but there is no way to express that concept in C++.

Now the using directive also does not help here because all it does is bring B::foo into the scope of C, meaning that it tells the compiler it should consider B::foo as a candidate for resolving the name foo when the latter is encountered inside class C. Unfortunately, that's also unrelated to the responsibility of implementing pure virtual methods.

Why an inherited interface can't be converted to its base interface in generic context?

You aren't able to make the assignment because the base class, AbstractClass<T>, is invariant. What you want to be able to make that kind of assignment is a covariant type. Defining Covariance and Contravariance is limited to interfaces, so that means we need another interface.

public interface IAbstractClass<out T> where T : BaseInterface { }  
public abstract class AbstractClass<T> : IAbstractClass<T> where T : BaseInterface { }

The out keyword marks the generic type parameter as covariant. We then implement that interface in AbstractClass<T>, and our other types can work expected through the interface. These are also the only alterations we need to make, we leave the other type definitions the same:

public interface BaseInterface { }
public interface ChildInterface : BaseInterface { }

public class ConcreteClass : AbstractClass<ChildInterface> { }

We now have a covariant interface that AbstractClass<T> implements, and you can do the kind of assignment you desire, but you'll have to target the IAbstractClass interface.

public void Main() {
IAbstractClass<BaseInterface> c = new ConcreteClass();
}

How do you declare an interface in C++?

To expand on the answer by bradtgmurray, you may want to make one exception to the pure virtual method list of your interface by adding a virtual destructor. This allows you to pass pointer ownership to another party without exposing the concrete derived class. The destructor doesn't have to do anything, because the interface doesn't have any concrete members. It might seem contradictory to define a function as both virtual and inline, but trust me - it isn't.

class IDemo
{
public:
virtual ~IDemo() {}
virtual void OverrideMe() = 0;
};

class Parent
{
public:
virtual ~Parent();
};

class Child : public Parent, public IDemo
{
public:
virtual void OverrideMe()
{
//do stuff
}
};

You don't have to include a body for the virtual destructor - it turns out some compilers have trouble optimizing an empty destructor and you're better off using the default.

Why interface cannot inherit pure abstract class

The major difference between interfaces and classes is that interfaces only provide signatures and not implementations. If the interface inheriting a class inherited its implementation, it would provide implementation and no longer be an interface.

Why is Multiple Inheritance not allowed in Java or C#?

The short answer is: because the language designers decided not to.

Basically, it seemed that both the .NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexity to the languages while providing too little benefit.

For a more fun and in-depth read, there are some articles available on the web with interviews of some of the language designers. For example, for .NET, Chris Brumme (who worked at MS on the CLR) has explained the reasons why they decided not to:

  1. Different languages actually have different expectations for how MI
    works. For example, how conflicts are
    resolved and whether duplicate bases
    are merged or redundant. Before we can
    implement MI in the CLR, we have to do
    a survey of all the languages, figure
    out the common concepts, and decide
    how to express them in a
    language-neutral manner. We would also
    have to decide whether MI belongs in
    the CLS and what this would mean for
    languages that don't want this concept
    (presumably VB.NET, for example). Of
    course, that's the business we are in
    as a common language runtime, but we
    haven't got around to doing it for MI
    yet.

  2. The number of places where MI is truly appropriate is actually quite
    small. In many cases, multiple
    interface inheritance can get the job
    done instead. In other cases, you may
    be able to use encapsulation and
    delegation. If we were to add a
    slightly different construct, like
    mixins, would that actually be more
    powerful?

  3. Multiple implementation inheritance injects a lot of complexity into the
    implementation. This complexity
    impacts casting, layout, dispatch,
    field access, serialization, identity
    comparisons, verifiability,
    reflection, generics, and probably
    lots of other places.

You can read the full article here.

For Java, you can read this article:

The reasons for omitting multiple
inheritance from the Java language
mostly stem from the "simple, object
oriented, and familiar" goal. As a
simple language, Java's creators
wanted a language that most developers
could grasp without extensive
training. To that end, they worked to
make the language as similar to C++ as
possible (familiar) without carrying
over C++'s unnecessary complexity
(simple).

In the designers' opinion, multiple
inheritance causes more problems and
confusion than it solves. So they cut
multiple inheritance from the language
(just as they cut operator
overloading). The designers' extensive
C++ experience taught them that
multiple inheritance just wasn't worth
the headache.

In C#, can a class inherit from another class and an interface?

Yes. Try:

class USBDevice : GenericDevice, IOurDevice

Note: The base class should come before the list of interface names.

Of course, you'll still need to implement all the members that the interfaces define. However, if the base class contains a member that matches an interface member, the base class member can work as the implementation of the interface member and you are not required to manually implement it again.

When should I choose inheritance over an interface when designing C# class libraries?

Generally, the rule goes something like this:

  • Inheritance describes an is-a relationship.
  • Implementing an interface describes a can-do relationship.

To put this in somewhat more concrete terms, let's look at an example. The System.Drawing.Bitmap class is-an image (and as such, it inherits from the Image class), but it also can-do disposing, so it implements the IDisposable interface. It also can-do serialization, so it implements from the ISerializable interface.

But more practically, interfaces are often used to simulate multiple inheritance in C#. If your Processor class needs to inherit from something like System.ComponentModel.Component, then you have little choice but to implement an IProcessor interface.

The fact is that both interfaces and abstract base class provide a contract specifying what a particular class can do. It's a common myth that interfaces are necessary to declare this contract, but that's not correct. The biggest advantage to my mind is that abstract base classes allow you provide default functionality for the subclasses. But if there is no default functionality that makes sense, there's nothing keeping you from marking the method itself as abstract, requiring that derived classes implement it themselves, just like if they were to implement an interface.

For answers to questions like this, I often turn to the .NET Framework Design Guidelines, which have this to say about choosing between classes and interfaces:

In general, classes are the preferred construct for exposing abstractions.

The main drawback of interfaces is that they are much less flexible than classes when it comes to allowing for the evolution of APIs. Once you ship an interface, the set of its members is fixed forever. Any additions to the interface would break existing types implementing the interface.

A class offers much more flexibility. You can add members to classes that you have already shipped. As long as the method is not abstract (i.e., as long as you provide a default implementation of the method), any existing derived classes continue to function unchanged.

[ . . . ]

One of the most common arguments in favor of interfaces is that they allow separating contract from the implementation. However, the argument incorrectly assumes that you cannot separate contracts from implementation using classes. Abstract classes residing in a separate assembly from their concrete implementations are a great way to achieve such separation.

Their general recommendations are as follows:

  • Do favor defining classes over interfaces.
  • Do use abstract classes instead of interfaces to decouple the contract from implementations. Abstract classes, if defined correctly, allow for the same degree of decoupling between contract and implementation.
  • Do define an interface if you need to provide a polymorphic hierarchy of value types.
  • Consider defining interfaces to achieve a similar effect to that of multiple inheritance.

Chris Anderson expresses particular agreement with this last tenet, arguing that:

Abstract types do version much better, and allow for future extensibility, but they also burn your one and only base type. Interfaces are appropriate when you are really defining a contract between two objects that is invariant over time. Abstract base types are better for defining a common base for a family of types.



Related Topics



Leave a reply



Submit