www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Multiple Inheritance

reply Olifant <olifant gmail.com> writes:
Say you have two interfaces: Visible and Selectable.

You want that everything that inherits from Visible, has the following two
functions:
SetVisible: sets it to visible or not
GetVisible: returns what you last set it to with SetVisible

You want that everything that inherits from Selectable, has the following two
functions:
SetSelected: sets it to selected or not
GetSelected: returns what you last set it to with SetSelected

Some classes inherit only from Visible, others only from Selectable, others
from both.

In C++, you can easily do this: put the implementations in the Visible and the
Selectable interface.

How can this be done in D? I mean to avoid that everyone who inherits from one
of them has to write his own implementation of
GetVisible/SetVisible/GetSelected/SetSelected over and over again, after all
it's always the same.

Is there some way to get such an effect with a language without multiple
inheritance, maybe even without inheritance at all, but still with the ability
to be able to make lists of Visible and of Selectable objects no matter what
subtype they are?
Sep 28 2007
next sibling parent Tomas Lindquist Olsen <tomas famolsen.dk> writes:
Olifant wrote:

 Say you have two interfaces: Visible and Selectable.
 
 You want that everything that inherits from Visible, has the following two
 functions: SetVisible: sets it to visible or not
 GetVisible: returns what you last set it to with SetVisible
 
 You want that everything that inherits from Selectable, has the following
 two functions: SetSelected: sets it to selected or not
 GetSelected: returns what you last set it to with SetSelected
 
 Some classes inherit only from Visible, others only from Selectable,
 others from both.
 
 In C++, you can easily do this: put the implementations in the Visible and
 the Selectable interface.
 
 How can this be done in D? I mean to avoid that everyone who inherits from
 one of them has to write his own implementation of
 GetVisible/SetVisible/GetSelected/SetSelected over and over again, after
 all it's always the same.
 
 Is there some way to get such an effect with a language without multiple
 inheritance, maybe even without inheritance at all, but still with the
 ability to be able to make lists of Visible and of Selectable objects no
 matter what subtype they are?

You could use mixins to provide a default implementation: interface Visible { bool visible(); void visible(bool); } interface Selectable { bool selected(); void selected(bool); } template VisibleImpl { private bool _isvisible; bool visible() { return _isvisible; } void visible(bool b) { _isvisible = b; } } template SelectedImpl { private bool _isselected; bool selected() { return _isselected; } void selected(bool b) { _isselected = b; } } class VisibleAndSelectable : Visible,Selectable { mixin VisibleImpl!(); mixin SelectedImpl!(); } Hope that helps :) -Tomas
Sep 28 2007
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Olifant" <olifant gmail.com> wrote in message 
news:fdij0a$2nup$1 digitalmars.com...
 Say you have two interfaces: Visible and Selectable.

 You want that everything that inherits from Visible, has the following two 
 functions:
 SetVisible: sets it to visible or not
 GetVisible: returns what you last set it to with SetVisible

 You want that everything that inherits from Selectable, has the following 
 two functions:
 SetSelected: sets it to selected or not
 GetSelected: returns what you last set it to with SetSelected

 Some classes inherit only from Visible, others only from Selectable, 
 others from both.

 In C++, you can easily do this: put the implementations in the Visible and 
 the Selectable interface.

 How can this be done in D? I mean to avoid that everyone who inherits from 
 one of them has to write his own implementation of 
 GetVisible/SetVisible/GetSelected/SetSelected over and over again, after 
 all it's always the same.

Three ways I can think of: 1. Define a base class that inherits from one of your implementations, and re-implements the second implementation. You will be re-implementing one implementation only once, and any derivatives that want both implementations can inherit from this base class. 2. You can encapsulate an implementation of each as members of the class, then declare the methods to call the encapsulated class' methods. 3. You can inherit from one implementation, then define an inner class that inherits from the other implementation. Redirect calls to the second implementation to the inner class. For example: class VisibleImpl : Visible { } class SelectableImpl : Selectable { } class BothImpl : VisibleImpl, Selectable { private class MySelectableImpl : SelectableImpl { // has access to BothImpl's members } private MySelectableImpl si = new MySelectableImpl; public override GetSelected() { return si.GetSelected(); } public override SetSelected() { return si.SetSelected(); } } -Steve
Sep 28 2007