Thread overview
private (aka no-inherit) implementations for public methods
Dec 04, 2009
Kevin Bealer
Dec 04, 2009
Bill Baxter
Dec 04, 2009
BCS
December 04, 2009
I think I have a solution to some problems that occur in OO design.  The problems occurs when a method can be implemented that provides a great functionality for a specific class, but which it is not valid for its subclasses without extra work.  The classic examples in C++ would be serialize.

void serialize(ostream&);

A class can always implement serialize(), but it's children will have to override the method with their own definition, which will probably call parent::serialize(), then go on to copy any added fields.  If they forget, the class does not return the right data (it loses the extra fields).

The solution: even though the method is public, make it possible to mark the implementation as non-inherited.  In other words, B will inherit the signature for clone() from A, but if the user attempts to link against B::clone() they had better implement it -- such a call will not resolve to A::clone().

If B wants to just use A's version they can just call A.serialize() in their method body.  It's not a private method, it just requires developer attention one way or the other to derive from the class.

I think this would make inheritance in OO design a lot less brittle.  Note that constructors (in C++ anyway) already have this property -- they aren't inherited by default (except the default constructor).

This is because methods like serialize, toString(), constructors, opCmp, etc are 'holistic' in the sense that they address all elements of a class and it is probably an error if they miss one.  Other methods like increaseRefCount() or getName() are field-wise operations that deal with a few select member variables.

Kevin

December 04, 2009
On Thu, Dec 3, 2009 at 10:15 PM, Kevin Bealer <kevinbealer@gmail.com> wrote:
> I think I have a solution to some problems that occur in OO design.  The problems occurs when a method can be implemented that provides a great functionality for a specific class, but which it is not valid for its subclasses without extra work.  The classic examples in C++ would be serialize.
>
> void serialize(ostream&);
>
> A class can always implement serialize(), but it's children will have to override the method with their own definition, which will probably call parent::serialize(), then go on to copy any added fields.  If they forget, the class does not return the right data (it loses the extra fields).
>
> The solution: even though the method is public, make it possible to mark the implementation as non-inherited.  In other words, B will inherit the signature for clone() from A, but if the user attempts to link against B::clone() they had better implement it -- such a call will not resolve to A::clone().
>
> If B wants to just use A's version they can just call A.serialize() in their method body.  It's not a private method, it just requires developer attention one way or the other to derive from the class.
>
> I think this would make inheritance in OO design a lot less brittle.  Note that constructors (in C++ anyway) already have this property -- they aren't inherited by default (except the default constructor).
>
> This is because methods like serialize, toString(), constructors, opCmp, etc are 'holistic' in the sense that they address all elements of a class and it is probably an error if they miss one.  Other methods like increaseRefCount() or getName() are field-wise operations that deal with a few select member variables.

Trouble is you have no idea exactly what behavior other classes are
going to extend.
It may not require reimplementing serialize, for instance.  Like
subclassing to implement ref-counting or something.  I don't think you
can determine up front which methods need to be overridden and which
do not.  It depends entirely upon how the subclass is going to extend
the base class.

--bb
December 04, 2009
Hello Bill,

> Trouble is you have no idea exactly what behavior other classes are
> going to extend.
> It may not require reimplementing serialize, for instance.  Like
> subclassing to implement ref-counting or something.  I don't think you
> can determine up front which methods need to be overridden and which
> do not.  It depends entirely upon how the subclass is going to extend
> the base class.
> --bb
> 

Because you can't determine up front which methods needn't be overridden and which must to be there should be a way to force this issues to be addressed by the author of the derived class.. For some cases, you can make an educated guess that in general some cases will need to be overridden (unless the user says otherwise).

vote++