www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - private (aka no-inherit) implementations for public methods

reply Kevin Bealer <kevinbealer gmail.com> writes:
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
Dec 03 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
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. =A0Th=
e problems occurs when a method can be implemented that provides a great fu= nctionality for a specific class, but which it is not valid for its subclas= ses without extra work. =A0The 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 par= ent::serialize(), then go on to copy any added fields. =A0If they forget, t= he 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. =A0In other words, B will inherit the = signature for clone() from A, but if the user attempts to link against B::c= lone() they had better implement it -- such a call will not resolve to A::c= lone().
 If B wants to just use A's version they can just call A.serialize() in th=
eir method body. =A0It's not a private method, it just requires developer a= ttention one way or the other to derive from the class.
 I think this would make inheritance in OO design a lot less brittle. =A0N=
ote that constructors (in C++ anyway) already have this property -- they ar= en'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 a= nd it is probably an error if they miss one. =A0Other methods like increase= RefCount() or getName() are field-wise operations that deal with a few sele= ct 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
Dec 04 2009
parent BCS <none anon.com> writes:
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++
Dec 04 2009