From: Leslie Sanford on
As a general rule, I shy away from implementation inheritance. However, I do
sometimes find it useful. My question is whether it's considered bad design
for a derived class method to call the base class method it is overriding.
Something like this:

class BaseClass
{
public:
virtual void DoSomething();
};

void BaseClass::DoSomething()
{
// Yadda, yadda...
}

class DerivedClass : public BaseClass
{
public:
void DoSomething();
};

void DerivedClass::DoSomething()
{
BaseClass::DoSomething();

// Yadda, yadda...
}

Is seems to me that this sort of thing could be the source of ambiguity. A
developer needs to know if calling the base class method is allowed, and if
so, when the base class method should be called, either at the beginning of
the overridden method or at the end.

As I said, I usually avoid implementation inheritance if possible, but
sometimes in refactoring code, I find it useful to push duplicated behavior
as far up the inheritance tree as possible. But I've sometimes found that
this means that an overridden method needs to call the base class method in
order to maintain the class's invariants. I want to avoid creating a mess,
though. And I want to be consistent in my design. Any feedback is
appreciated.


From: Dmitry A. Kazakov on
On Fri, 11 Jan 2008 13:45:25 -0600, Leslie Sanford wrote:

> My question is whether it's considered bad design
> for a derived class method to call the base class method it is overriding.

Of course not. How constructors could work otherwise? It makes a lot sense
to have extensible methods, when the base type could enforce execution of
some code in the prologue or epilogue of specific body of the method.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: H. S. Lahman on
Responding to Sanford...

> As a general rule, I shy away from implementation inheritance. However, I do
> sometimes find it useful. My question is whether it's considered bad design
> for a derived class method to call the base class method it is overriding.
> Something like this:
>
> class BaseClass
> {
> public:
> virtual void DoSomething();
> };
>
> void BaseClass::DoSomething()
> {
> // Yadda, yadda...
> }
>
> class DerivedClass : public BaseClass
> {
> public:
> void DoSomething();
> };
>
> void DerivedClass::DoSomething()
> {
> BaseClass::DoSomething();
>
> // Yadda, yadda...
> }

But this is not implementation inheritance; the BaseClass::DoSomething
method is explicitly called in the subclass implementation rather than
being resolved by inheritance. This is no different than

class Standalone1
{
public:
void DoSomething();
}

class Standalone2
{
public:
void DoIt()
private:
Standalone1* myStandalone1; // implement peer association
}

void Standalone2::DoIt()
{
myStandalone1->DoSomething();
...
}

The reason we avoid implementation inheritance is because it adds a
dimension of complexity to resolving what implementation actually gets
invoked when access is polymorphic. The problem lies in maintenance.
During maintenance it is possible to break existing clients when the
implementation definition is moved (very rare) or when implementation
overrides are used (a much more common problem). That's because the
actual implementation is resolved through the inheritance mechanism.
Therefore changes to the generalization tree may change which
implementation actually gets invoked even though clients may still
access the tree the same way with the same expectations.

But when one explicitly invokes the method in the leaf subclass it
doesn't matter where that implementation is. Using the generalization
tree is just a convenient mechanism for organizing how the developer
thinks about the problem space. Consequently there is no ambiguity about
which implementation the leaf subclass uses. Thus your example
represents the preferred way to eliminate code redundancy because it is
quite explicit which implementation is to be used _at the leaf subclass
level_. IOW, it doesn't matter how the generalization tree is modified
subsequently (e.g., how many levels are inserted or how many alternative
implementations are added in other superclasses); the subclass will
still invoke the same implementation.


--
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
From: Daniel T. on
"Leslie Sanford" <jabberdabber(a)bitemehotmail.com> wrote:

> As a general rule, I shy away from implementation inheritance. However, I do
> sometimes find it useful. My question is whether it's considered bad design
> for a derived class method to call the base class method it is overriding.

I think HS's response was good, but I would like to expand on it some...

> Something like this:
>
> class BaseClass
> {
> public:
> virtual void DoSomething();
> };
>
> void BaseClass::DoSomething()
> {
> // Yadda, yadda...
> }
>
> class DerivedClass : public BaseClass
> {
> public:
> void DoSomething();
> };
>
> void DerivedClass::DoSomething()
> {
> BaseClass::DoSomething();
>
> // Yadda, yadda...
> }
>
> Is seems to me that this sort of thing could be the source of ambiguity. A
> developer needs to know if calling the base class method is allowed, and if
> so, when the base class method should be called, either at the beginning of
> the overridden method or at the end.

Note, the derived class needs to know that about every base class method
(if and when to call it.) It's fair to say that such information is
required of every method/function in the program. So its not much of a
burden.

To expand on HSs example... How is your code above any different than:

class BaseInterface {
public:
virtual void DoSomething() = 0;
};

class BaseImplementation {
public:
void DoSomething() { /* Yadda, yadda...*/ }
};

class DerivedClass : public BaseInterface {
BaseImplementation impl;
public:
void DoSomething() {
impl.DoSomething();
// Yadda, yadda...
}
};

In your code, implementation inheritance is used, in my example it is
not. As long as the BaseClass contains no data and has no non-virtual
member functions, your example is every bit as flexible as mine and your
example requires fewer classes.

> As I said, I usually avoid implementation inheritance if possible, but
> sometimes in refactoring code, I find it useful to push duplicated behavior
> as far up the inheritance tree as possible. But I've sometimes found that
> this means that an overridden method needs to call the base class method in
> order to maintain the class's invariants. I want to avoid creating a mess,
> though. And I want to be consistent in my design. Any feedback is
> appreciated.

I don't have a problem with implementation inheritance, except when it
comes to data containment and non-virtual member-functions. I.E., those
things which the derived classes simply cannot change. I also have a big
problem with base classes that are not abstract (in static typed
languages like C++,) that means you are missing an abstraction in your
code.
From: Leslie Sanford on
"Daniel T." wrote:
> "Leslie Sanford" wrote:

<snip>

> Note, the derived class needs to know that about every base class method
> (if and when to call it.) It's fair to say that such information is
> required of every method/function in the program. So its not much of a
> burden.

I was using a third-party library recently in which I had a hard time
tracking down an obscure bug. I had derived a class from one of the
library's base classes. This class has many virtual methods that you can
override to provide your own custom behavior.

The problem turned out to be that I wasn't calling the base class method in
my derived class's overriden method. This requirement wasn't mentioned any
where in the documentation. I guess what would be nice would be some type of
language mechanism that would enforce the correct policy, when/if to call
the base class's method in a derived classes overriden version of that
method.

> To expand on HSs example... How is your code above any different than:
>
> class BaseInterface {
> public:
> virtual void DoSomething() = 0;
> };
>
> class BaseImplementation {
> public:
> void DoSomething() { /* Yadda, yadda...*/ }
> };
>
> class DerivedClass : public BaseInterface {
> BaseImplementation impl;
> public:
> void DoSomething() {
> impl.DoSomething();
> // Yadda, yadda...
> }
> };
>
> In your code, implementation inheritance is used, in my example it is
> not. As long as the BaseClass contains no data and has no non-virtual
> member functions, your example is every bit as flexible as mine and your
> example requires fewer classes.

Ok, but what if the BaseClass does have data? In the situation I described
above, the base class's virtual methods had behavior that managed the
class's state. If a derived class overrides one of those methods and does
not call the base class method when it is called, the class's invariants may
be violated. I guess there's something about this that just doesn't sit
right with me. You'd have to rely on documenation to know when/if you have
to call the base class's method.

Should a base class be designed in such a way that an overriden method can
always call the base class's method without bad things happening?