Mohikani McIntyre
Mohikani McIntyre

Reputation: 11

can an abstract class inherit from a "normal" class?

I am looking for a useful example of multiple inheritance in C++ and found an example for Window-creation here: A use for multiple inheritance? and modified it a bit. It conceptually looks like this:

class Window
class Skinable  // abstract
class Draggable // abstract
class DraggableSkinnableWindow : Window, Draggable, Skinnable

I think this is supposed to be a good example where MI makes sense. Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.

Now: How would this look like if I would not use the concept of MI. I would have used a simple hierarchical structure like this:

class  Window
class Dragable : public Window
class Skinable : public Dragable
class DraggableSkinnableWindow : Skinnable

I still want Dragable and Skinable to be abstract as well but is that even possible? Is the second example even a good solution for the same context but not using MI?

Thank you in advance!

Upvotes: 1

Views: 1813

Answers (3)

luk32
luk32

Reputation: 16080

I think this is supposed to be a good example where MI makes sense.

It does, at long as Window, Draggable, Skinnable do not share common ancestor, at least other than pure abstract, otherwise you would need virtual inheritance.

Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.

It can make sense, for example defining a property skin + setters and getters. You seem to be confusing abstract classes and pure abstract classes. Abstract classes have at least one pure virtual function, which means you cannot instantiate them. Pure abstract classes do not have any implementation of any method, they contain only pure virtual functions, and are often used as a realization interface concept in c++.

How would this look like if I would not use the concept of MI. Is the second example even a good solution for the same context but not using MI?

You cannot do it properly. c++ does not differentiate between classes and interfaces (as it does not provide such concept on language level). It is the same as stripping java or c# of interfaces. It would be possible if you provided all the compounds by hand i.e. Skinnable, Draggable bases, would produce SkinnableDraggable and/or DraggableSkinnable (which would probably be equivalent) dervided classes. This is quite a killer.

Your example, as others mentioned completely mixes unrelated concepts. E.g. Your Draggables and Skinnables must be Windowses. This is not obvious, and certainly not correct in general.

Upvotes: 1

Emerald Weapon
Emerald Weapon

Reputation: 2540

I would probably go like this

 class Window
 class Draggable : public virtual Window
 class Skinnable : public virtual Window
 class DraggableSkinnableWindow : Draggable, Skinnable

And provide default implementation in the pure virtual methods contained in Draggabel and Skinnable separately

class Draggable : public virtual Window {

    virtual void aMethod() = 0;
    void aMethodDefaultImplementation() = { //...// }; 
}

then inside DraggableSkinnable you have two options:

virtual void aMethod() = { aMethodDefaultImplementation() };

or

virtual void aMethod() = {// ...non-default implementation... //};

This has the benefit of providing a default implementation if you need one (as if aMethod was not pure virtual) but forcing you to ask for that explicitly (because it is purely virtual).

Upvotes: 1

Aluan Haddad
Aluan Haddad

Reputation: 31863

While your example is a solid use case for multiple inheritance, I disagree with the assertion that it does not make sense for Skinnable to have an implementation. Rather, as @devianfan alluded to in his comment, your single inheritance alternative fails to model the conceptual taxonomy.

It is about cross axial classifications. A window is both skinabble and draggable but neither of these qualities are codependent.

Consider that, as suggested by your example domain, your application code consists of a collection of graphical user interface elements. You might want to perform perform operations on subgroups of them based on their capabilities. For example you might manipulate the appearance of all skinnable elements based on some customization. On the other hand, there are probably elements of your GUI which are draggable and should be notified on certain user input events. A window is a good example of something which falls into both categories.

Upvotes: 1

Related Questions