Different kind of inheritance/Multiple Inheritance 
Author Message
 Different kind of inheritance/Multiple Inheritance

Quote:

> I am reading the chapter on multiple inheritance in Bertrand Meyer's
> "Object-oriented Software Construction, 2nd Ed." and have a question.  The
> book used several examples that looks like this:

> A composite figure (e.g. a combination of two shapes that can be
> manipulated as one) is a figure and also a list of the subfigures that it
> is made up of.

> <begin quote>
> class COMPOSITE_FIGURE inherit
>    FIGURE
>    LINKED_LIST[FIGURE]
>    ...
> <end quote>

> ...In both cases there seems to be different use of the inheritance
> mechanism.  COMPOSITE_FIGURE "is a" FIGURE in the way that it supports the
> interface of FIGURE.  It "is a" LINKED_LIST[FIGURE] because it is
> "implemented as" a LINKED_LIST.

> I am confuse by the use of inheritance in the second case...

Eiffel gives you the best of both worlds - it allows you to access
implementation details by either client-supplier or inheritance, and both
approaches can work well. It's a stylistic choice - nothing forces you to use
inheritance if you don't want to. Many Eiffel users prefer not to
inherit implementation details, although ISE and Bertrand Meyer seem to lean
strongly towards the inheritance solution.

I'm not advocating that you choose to inherit your implementation (I usually
use client-supplier in my own code), but I want to show that it doesn't have
all the problems you ascribe to it - it actually works rather well in Eiffel.

Quote:
> 1) It violates information hiding by exposing/exporting the LINKED_LIST
> interface...

If you are concerned, you can solve this problem by re-exporting to NONE, e.g:

   class COMPOSITE_FIGURE
   inherit
      ...
      LINKED_LIST[FIGURE]
         export {NONE} all
      end

Although you can still assign COMPOSITE_FIGURE polymorphically to an attribute
of type LINKED_LIST[FIGURE], you can't call any features on it because the
interface is not exposed.

However, it's not always black-and-white which parent class is "is-a" and
which is "uses". Often, they may all be "is-a" in ways which the original
class designer hasn't anticipated. For example, someone might write a test
harness to exercise (polymorphically) a number of classes descended from
LINKED_LIST[FIGURE]. OK, I know that sounds far-fetched for this particular
example, but in many cases it's more likely.

Furthermore, Eiffel inheritance allows you to adapt parent classes on a
feature-by-feature basis. You often find a situation where "is-a" applies to a
certain subset of the features of the parent class. In this case, hiding the
"uses" features works well. This technique allows you to effectively use
"is-a" with a general-purpose library class that includes some features
inappropriate to the abstraction represented by your child class.

Quote:
> 2) It use of MI invokes the need for feature renaming by causing a name
> conflict between some function/class members of classes FIGURE and
> LINKED_LIST.

Yes - but renaming works well in Eiffel and doesn't disturb polymorphism and
dynamic binding (which work on feature identity, not feature name).

Quote:
> My question is: Is inheriting COMPOSITE_FIGURE from LINKED_LIST justified
> in the above case, and would it be better/worse (and why?) to use
> LINKED_LIST as a member?

One advantage of using LINKED_LIST as an attribute or local entity ("member")
is that you can easily substitute a subtype of LINKED_LIST with just a
one-line change to your program. If you inherit from LINKED_LIST, changing
your application to inherit from a subtype of LINKED_LIST may introduce more
name clashes, and therefore require more changes to your program.

You can even choose your implementation at runtime - such flexibility is
impossible with the inheritance approach. For example:

   implementation: LINKED_LIST[FIGURE]
   ...
   if speed_is_critical then
      !FAST_LINKED_LIST[FIGURE]!implementation.make
   else
      !MEMORY_EFFICIENT_LINKED_LIST[FIGURE]!implementation.make
   end

Regards,
Roger
--
--
-- Roger Browne, 6 Bambers Walk, Wesham, PR4 3DG, UK | Ph 01772-687525
-- Everything Eiffel: http://www.*-*-*.com/ | +44-1772-687525



Sun, 19 Dec 1999 03:00:00 GMT  
 Different kind of inheritance/Multiple Inheritance

Quote:


> > I am reading the chapter on multiple inheritance in Bertrand Meyer's

> > "Object-oriented Software Construction, 2nd Ed." and have a
> question.  The
> > book used several examples that looks like this:

> > A composite figure (e.g. a combination of two shapes that can be
> > manipulated as one) is a figure and also a list of the subfigures
> that it
> > is made up of.

> > <begin quote>
> > class COMPOSITE_FIGURE inherit
> >       FIGURE
> >       LINKED_LIST[FIGURE]
> >       ...
> > <end quote>

> > ...In both cases there seems to be different use of the inheritance
> > mechanism.  COMPOSITE_FIGURE "is a" FIGURE in the way that it
> supports the
> > interface of FIGURE.  It "is a" LINKED_LIST[FIGURE] because it is
> > "implemented as" a LINKED_LIST.

> > I am confuse by the use of inheritance in the second case...

> Eiffel gives you the best of both worlds - it allows you to access
> implementation details by either client-supplier or inheritance, and
> both
> approaches can work well. It's a stylistic choice - nothing forces you
> to use
> inheritance if you don't want to. Many Eiffel users prefer not to
> inherit implementation details, although ISE and Bertrand Meyer seem
> to lean
> strongly towards the inheritance solution.

> I'm not advocating that you choose to inherit your implementation (I
> usually
> use client-supplier in my own code), but I want to show that it
> doesn't have
> all the problems you ascribe to it - it actually works rather well in
> Eiffel.

> > 1) It violates information hiding by exposing/exporting the
> LINKED_LIST
> > interface...

> If you are concerned, you can solve this problem by re-exporting to
> NONE, e.g:

>    class COMPOSITE_FIGURE
>    inherit
>       ...
>       LINKED_LIST[FIGURE]
>          export {NONE} all
>       end

> Although you can still assign COMPOSITE_FIGURE polymorphically to an
> attribute
> of type LINKED_LIST[FIGURE], you can't call any features on it because
> the
> interface is not exposed.

> However, it's not always black-and-white which parent class is "is-a"
> and
> which is "uses". Often, they may all be "is-a" in ways which the
> original
> class designer hasn't anticipated. For example, someone might write a
> test
> harness to exercise (polymorphically) a number of classes descended
> from
> LINKED_LIST[FIGURE]. OK, I know that sounds far-fetched for this
> particular
> example, but in many cases it's more likely.

> Furthermore, Eiffel inheritance allows you to adapt parent classes on
> a
> feature-by-feature basis. You often find a situation where "is-a"
> applies to a
> certain subset of the features of the parent class. In this case,
> hiding the
> "uses" features works well. This technique allows you to effectively
> use
> "is-a" with a general-purpose library class that includes some
> features
> inappropriate to the abstraction represented by your child class.

> > 2) It use of MI invokes the need for feature renaming by causing a
> name
> > conflict between some function/class members of classes FIGURE and
> > LINKED_LIST.

> Yes - but renaming works well in Eiffel and doesn't disturb
> polymorphism and
> dynamic binding (which work on feature identity, not feature name).

> > My question is: Is inheriting COMPOSITE_FIGURE from LINKED_LIST
> justified
> > in the above case, and would it be better/worse (and why?) to use
> > LINKED_LIST as a member?

> One advantage of using LINKED_LIST as an attribute or local entity
> ("member")
> is that you can easily substitute a subtype of LINKED_LIST with just a

> one-line change to your program. If you inherit from LINKED_LIST,
> changing
> your application to inherit from a subtype of LINKED_LIST may
> introduce more
> name clashes, and therefore require more changes to your program.

> You can even choose your implementation at runtime - such flexibility
> is
> impossible with the inheritance approach. For example:

>    implementation: LINKED_LIST[FIGURE]
>    ...
>    if speed_is_critical then
>       !FAST_LINKED_LIST[FIGURE]!implementation.make
>    else
>       !MEMORY_EFFICIENT_LINKED_LIST[FIGURE]!implementation.make
>    end

Agreed.  However, inheriting from LINKED_LIST[FIGURE] has one advantage
(and it's the only one I can see):  you may want to provide features in
COMPOSITE_FIGURE to iterate over its constituent figures.  By inheriting
from LINKED_LIST, you inherit the desired features.  Otherwise, you'll
have to write your own `next', `item', etc.  This may not be so bad
because these features will be simple wrappers around calls to the
LINKED_LIST[FIGURE] (or whatever you decide to use) attribute.

So, in this case, inheriting saves you writing a few wrappers.

- Show quoted text -

Quote:
> Regards,
> Roger
> --
> --
> -- Roger Browne, 6 Bambers Walk, Wesham, PR4 3DG, UK | Ph 01772-687525

> -- Everything Eiffel: http://www.eiffel.demon.co.uk/ | +44-1772-687525



Mon, 20 Dec 1999 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Multiple Dispatch (was Re: Replacing Multiple Inheritance with Java's Interfaces)

2. Public inheritance (was: Restricting inheritance)

3. Inheritance: Interface vs Implementation (was: Questions on inheritance)

4. 2 Kinds of Inheritance

5. Exchanging objects between programs with different inheritance hierarchies

6. Smalltalk and Multiple Inheritance

7. Free Multiple Inheritance for VisualWorks 2.0

8. Multiple inheritance

9. Multiple Inheritance

10. Is Multiple inheritance possible in VA 2.0

11. multiple inheritance?

12. Multiple inheritance in smalltalk

 

 
Powered by phpBB® Forum Software