Interface inheritance vs Implementation inheritance.

Discussion in 'Java' started by Daniel Pitts, Feb 19, 2008.

  1. Daniel Pitts

    Daniel Pitts Guest

    (x-posted to c.object and c.l.java.programmer)
    First, a quick bit about my background; most of my OO experience comes
    from Java, with some C++ in my past. Recently in comp.object, there was
    a thread "Inheritance of implementation: what is reason of". While the
    subject line could use some grammatic tweaking, the point was eventually
    made clear.

    I was thinking about it, and it seems to me that implementation
    inheritance is a convenience that leads to bad design and mistakes. By
    convenience, I mean that often a programmer will design the an interface
    and the implementation together in one source unit (e.g. a class).
    Alternatively, you can define a separate interface (lets call it IFoo)
    in one source unit, and an implementation (FooImpl). FooImpl is *also*
    an interface in many languages, it just happens to have the associated
    implementation.

    So far, not that big of a deal. The convolution comes when you add in
    access modifiers. For instance, in Java you can mark methods/fields as
    private, protected, package-private, or public. Now, you have up to 4
    interfaces to the implementation. Only certain code units can see some
    of the interfaces, but managing that contract becomes troublesome,
    especially for the "protected" interface, as many programmers don't
    design their classes for inheritance but the class gets used that way.

    To me, polymorphic behavior is important, and "implementation sharing"
    is a very useful convenience. I think that they are often co-mingled
    concepts that should be separated. I have a few ideas on how I might do
    this, at the language level, but I wanted to see if my above thoughts on
    the subject stirred any interesting discussions.

    My main point is that classes should use composition to gain behavior,
    possibly with an easy mechanism for delegation. The *only* thing that
    should be automatically inherited should be the interface. This
    eliminates the need for (and usefulness of) the "protected" access modifier.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 19, 2008
    #1
    1. Advertising

  2. "Daniel Pitts" <> wrote in message
    news:47bb1b08$0$3040$...
    > (x-posted to c.object and c.l.java.programmer)
    >
    > My main point is that classes should use composition to gain behavior,
    > possibly with an easy mechanism for delegation. The *only* thing that
    > should be automatically inherited should be the interface. This
    > eliminates the need for (and usefulness of) the "protected" access
    > modifier.
    >


    In C++ there are various ways implementation inheritance is useful in ways
    other than inheritance of default implementation, e.g. STL, ATL, WTL, all of
    which use some form of implementation inheritance to achieve efficiency.

    I think the primary problem people are concerned about is implementation of
    inheritance for virtual functions. Perhaps this distinction is not
    meaningful outside of the C++ world.

    Andrew
    andrew queisser, Feb 19, 2008
    #2
    1. Advertising

  3. Daniel Pitts

    Peter Duniho Guest

    On Tue, 19 Feb 2008 10:08:17 -0800, Daniel Pitts
    <> wrote:

    > [...]
    > My main point is that classes should use composition to gain behavior,
    > possibly with an easy mechanism for delegation. The *only* thing that
    > should be automatically inherited should be the interface. This
    > eliminates the need for (and usefulness of) the "protected" access
    > modifier.


    I have a sense that in spite of asking the question, you may have already
    decided on the answer. I don't intend to get sucked too deep into this
    conversation. Especially given the somewhat dubious cross-posting.

    That said, I disagree. I do agree that inheriting an implementation and
    implementing an interface are not the same thing, but I disagree that only
    the latter is a viable approach. Both are important and useful approaches
    in OOP. Interfaces are good for when there's a specific abstract contract
    that any object ought to be able to fulfill. Inheriting implementation is
    good for when an object really "is" a more-specific version of some
    existing object. And of course composition is also useful, when your
    object isn't really a more-specific version of some existing object but
    you still need to take advantage of an existing implementation of an
    object.

    In Java, why should a new class that inherits Container have to
    reimplement all of the Container class's containment interface? If all
    you want to do is provide a Container with some specific visual behavior,
    why should you also have to reimplement all of the non-visual containment
    behavior when there's a working, useful class that already does all that?

    Likewise, abstract classes often (in fact, usually IME, otherwise they'd
    be interfaces) provide _some_ functionality that only needs one or a few
    actual abstract members to be implemented in order to get the full
    functionality of the abstract class. For example, InputStream in Java
    where you only have to implement "int read()" in a derived class in order
    for the other two InputStream methods that read data to work. There are
    often performance advantages to overriding those other two methods as
    well, but if that's not a design goal why should the implementor of the
    derived class be forced to reimplement them anyway (especially given that
    they are very likely to just reimplement them exactly as the abstract
    class has implemented them, except possibly by reintroducing all the bugs
    that the original implementor already found and fixed in their
    implementation).

    Is inheritance overused? I'd agree that it is. Programmers often inherit
    when they should either composite or implement an interface instead. But
    I disagree that that somehow means that inheriting an implementation is a
    priori bad. There is still plenty of good examples of useful and proper
    inheritance of an implementation.

    Pete
    Peter Duniho, Feb 19, 2008
    #3
  4. Daniel Pitts

    Daniel Pitts Guest

    Peter Duniho wrote:
    > On Tue, 19 Feb 2008 10:08:17 -0800, Daniel Pitts
    > <> wrote:
    >
    >> [...]
    >> My main point is that classes should use composition to gain behavior,
    >> possibly with an easy mechanism for delegation. The *only* thing that
    >> should be automatically inherited should be the interface. This
    >> eliminates the need for (and usefulness of) the "protected" access
    >> modifier.

    >
    > I have a sense that in spite of asking the question, you may have
    > already decided on the answer. I don't intend to get sucked too deep
    > into this conversation. Especially given the somewhat dubious
    > cross-posting.

    I only cross-posted to cljp because I'm regular there, and appreciate
    their input.
    >
    > That said, I disagree. I do agree that inheriting an implementation and
    > implementing an interface are not the same thing, but I disagree that
    > only the latter is a viable approach. Both are important and useful
    > approaches in OOP. Interfaces are good for when there's a specific
    > abstract contract that any object ought to be able to fulfill.
    > Inheriting implementation is good for when an object really "is" a
    > more-specific version of some existing object. And of course
    > composition is also useful, when your object isn't really a
    > more-specific version of some existing object but you still need to take
    > advantage of an existing implementation of an object.
    >
    > In Java, why should a new class that inherits Container have to
    > reimplement all of the Container class's containment interface? If all
    > you want to do is provide a Container with some specific visual
    > behavior, why should you also have to reimplement all of the non-visual
    > containment behavior when there's a working, useful class that already
    > does all that?

    That is a perfectly valid point. My thoughts are that it should be
    *easy* to "borrow" implementation from another object, without using
    inheritance but instead using composition. To borrow your Container
    example: Say you have MyContainer which implements the Container
    interface, and delegates (with as clean a syntax as possible) most of
    its behavior to another Container instance. You don't have to
    re-implement the containment behavior.
    >
    > Likewise, abstract classes often (in fact, usually IME, otherwise they'd
    > be interfaces) provide _some_ functionality that only needs one or a few
    > actual abstract members to be implemented in order to get the full
    > functionality of the abstract class. For example, InputStream in Java
    > where you only have to implement "int read()" in a derived class in
    > order for the other two InputStream methods that read data to work.
    > There are often performance advantages to overriding those other two
    > methods as well, but if that's not a design goal why should the
    > implementor of the derived class be forced to reimplement them anyway
    > (especially given that they are very likely to just reimplement them
    > exactly as the abstract class has implemented them, except possibly by
    > reintroducing all the bugs that the original implementor already found
    > and fixed in their implementation).

    I think what you just described is related to (but not exactly) the
    Template design pattern. I think that the problem solved by the Template
    pattern can be solved using a callback pattern instead.
    >
    > Is inheritance overused? I'd agree that it is. Programmers often
    > inherit when they should either composite or implement an interface
    > instead. But I disagree that that somehow means that inheriting an
    > implementation is a priori bad. There is still plenty of good examples
    > of useful and proper inheritance of an implementation.

    I'm not saying that it is always and automatically bad. I guess my main
    point was that there are situations where, due to many language
    limitations, it is necessary to avoid a massive amounts of boiler-plate
    delegation code. If you had a convenient way (say one or two source
    lines) to "borrow" all/most implementation from another class, would you
    still feel that implementation inheritance is still necessary?

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 19, 2008
    #4
  5. Daniel Pitts

    Peter Duniho Guest

    On Tue, 19 Feb 2008 13:27:19 -0800, Daniel Pitts
    <> wrote:

    > [...]
    > I'm not saying that it is always and automatically bad. I guess my main
    > point was that there are situations where, due to many language
    > limitations, it is necessary to avoid a massive amounts of boiler-plate
    > delegation code. If you had a convenient way (say one or two source
    > lines) to "borrow" all/most implementation from another class, would you
    > still feel that implementation inheritance is still necessary?


    I guess I can only at this point answer "it depends". It seems to me that
    the current, widely-used implementation inheritance syntax is pretty much
    just that: a convenient way to borrow implementation from another class.

    I would have to see what this alternative syntax would look like to answer
    more definitively, but it's not clear to me that it'd be any different in
    practice from simply inheriting an implementation directly (assuming that,
    as with interfaces, a "borrowing" class still tests "true" for whether it
    "is" one of these "borrowed" things...if that's not the case, then I'd say
    that's a glaring omission of the proposal).

    Or, looking at the question from another angle, if it's okay to "borrow"
    implementation from another class, what does it matter whether it was
    borrowed in the form of inheritance or in the form of a new type of
    composition that looks just like inheritance?

    I'm reading this in the Java newsgroup, and perhaps the "comp.object"
    crowd has a more thorough academic understanding of OOP practices and
    principles than I do. But I admit, based on what you've written so far
    I'm not really clear on the distinction between the way things are now and
    what you're suggesting they could be, at least from a practical standpoint.

    Pete
    Peter Duniho, Feb 19, 2008
    #5
  6. Peter Duniho wrote:
    ....
    > Or, looking at the question from another angle, if it's okay to "borrow"
    > implementation from another class, what does it matter whether it was
    > borrowed in the form of inheritance or in the form of a new type of
    > composition that looks just like inheritance?

    ....

    I think the big question is what gets exposed to users of the borrowing
    class.

    To make this a bit more specific, consider ArrayList. It implements a
    series of interfaces. Those describe the general behavior its callers
    can depend on: it's a list, it has fast random access, it can be cloned
    and serialized, and it has an Iterator.

    In addition, it extends AbstractList. That seems to me to be part of its
    implementation, and not something I would use in my code. And yet, a
    class outside java.util could declare:

    AbstractList<String> someList = new ArrayList<String>();

    It might be advantageous to split AbstractList, for example to provide
    different implementations depending on whether the list has fast random
    access. That cannot be done, because of the public nature of the uses of
    AbstractList.

    Patricia
    Patricia Shanahan, Feb 19, 2008
    #6
  7. Daniel Pitts

    Daniel Pitts Guest

    Peter Duniho wrote:
    > On Tue, 19 Feb 2008 13:27:19 -0800, Daniel Pitts
    > <> wrote:
    >
    >> [...]
    >> I'm not saying that it is always and automatically bad. I guess my
    >> main point was that there are situations where, due to many language
    >> limitations, it is necessary to avoid a massive amounts of
    >> boiler-plate delegation code. If you had a convenient way (say one or
    >> two source lines) to "borrow" all/most implementation from another
    >> class, would you still feel that implementation inheritance is still
    >> necessary?

    >
    > I guess I can only at this point answer "it depends". It seems to me
    > that the current, widely-used implementation inheritance syntax is
    > pretty much just that: a convenient way to borrow implementation from
    > another class.

    Currently, inheritance of classes "borrows" both the implementation
    *and* interface. The thing is that interface and implementation are
    borrowed together, and you have to take extra steps if you only want the
    implementation or only the interface. I think it might be good to
    separate those concepts.
    >
    > I would have to see what this alternative syntax would look like to
    > answer more definitively, but it's not clear to me that it'd be any
    > different in practice from simply inheriting an implementation directly
    > (assuming that, as with interfaces, a "borrowing" class still tests
    > "true" for whether it "is" one of these "borrowed" things...if that's
    > not the case, then I'd say that's a glaring omission of the proposal).

    If the interface "lives" separately from the implementation, then the
    borrow can choose to also borrow the interface (or some parent
    interface, or some composite interface).

    > Or, looking at the question from another angle, if it's okay to "borrow"
    > implementation from another class, what does it matter whether it was
    > borrowed in the form of inheritance or in the form of a new type of
    > composition that looks just like inheritance?

    Because the borrowing can be more pick-and-choose in the new way,
    instead of the all-or-nothing of inheritance. Also, there are times when
    your interface maps one-to-one to another class for a few methods. It
    could be easier to pick out those methods.
    >
    > I'm reading this in the Java newsgroup, and perhaps the "comp.object"
    > crowd has a more thorough academic understanding of OOP practices and
    > principles than I do. But I admit, based on what you've written so far
    > I'm not really clear on the distinction between the way things are now
    > and what you're suggesting they could be, at least from a practical
    > standpoint.

    I guess the main difference is the syntax, but I believe it adds
    flexibility too.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 19, 2008
    #7
  8. On 2008-02-19 23:10 +0100, Daniel Pitts allegedly wrote:
    > Peter Duniho wrote:
    >> On Tue, 19 Feb 2008 13:27:19 -0800, Daniel Pitts
    >> <> wrote:
    >>
    >>> [...] I'm not saying that it is always and automatically bad. I
    >>> guess my main point was that there are situations where, due to
    >>> many language limitations, it is necessary to avoid a massive
    >>> amounts of boiler-plate delegation code. If you had a convenient
    >>> way (say one or two source lines) to "borrow" all/most
    >>> implementation from another class, would you still feel that
    >>> implementation inheritance is still necessary?

    >>
    >> I guess I can only at this point answer "it depends". It seems to
    >> me that the current, widely-used implementation inheritance syntax
    >> is pretty much just that: a convenient way to borrow implementation
    >> from another class.

    > Currently, inheritance of classes "borrows" both the implementation
    > *and* interface. The thing is that interface and implementation are
    > borrowed together, and you have to take extra steps if you only want
    > the implementation or only the interface. I think it might be good
    > to separate those concepts.
    >>
    >> I would have to see what this alternative syntax would look like to
    >> answer more definitively, but it's not clear to me that it'd be
    >> any different in practice from simply inheriting an implementation
    >> directly (assuming that, as with interfaces, a "borrowing" class
    >> still tests "true" for whether it "is" one of these "borrowed"
    >> things...if that's not the case, then I'd say that's a glaring
    >> omission of the proposal).

    > If the interface "lives" separately from the implementation, then the
    > borrow can choose to also borrow the interface (or some parent
    > interface, or some composite interface).
    >
    >> Or, looking at the question from another angle, if it's okay to
    >> "borrow" implementation from another class, what does it matter
    >> whether it was borrowed in the form of inheritance or in the form
    >> of a new type of composition that looks just like inheritance?

    > Because the borrowing can be more pick-and-choose in the new way,
    > instead of the all-or-nothing of inheritance. Also, there are times
    > when your interface maps one-to-one to another class for a few
    > methods. It could be easier to pick out those methods.
    >>
    >> I'm reading this in the Java newsgroup, and perhaps the
    >> "comp.object" crowd has a more thorough academic understanding of
    >> OOP practices and principles than I do. But I admit, based on what
    >> you've written so far I'm not really clear on the distinction
    >> between the way things are now and what you're suggesting they
    >> could be, at least from a practical standpoint.

    > I guess the main difference is the syntax, but I believe it adds
    > flexibility too.
    >


    /* The following deliberately sets itself strictly within the context of
    the Java Programming Language, as it often most beneficial to have a
    practical reference to focus the discussion. */

    It seems to me all practical examples you gave in this thread are
    feasible with the current grammar of Java. There are two discrete
    models, one for "borrowing" an interface and one for "borrowing" an
    implementation; the first one is called implementing an interface and
    the second one extending a class.
    The practice of always providing both for all classes isn't ubiquitous,
    or even widespread. But, while I grant this may cause you much grief on
    diverse occasions, it is simply not an argument against the grammar of
    Java, but only potentially against some of its uses.
    On the subject of "borrowing an implementation", let me point out that
    getting rid of protected modifiers, which you seem to aim at, would
    effectively _force_ upon you _all_ the implementation that isn't public
    -- so much for "borrowing can be more pick-and-choose".

    The use of composition in a given class is clearly a good idea and
    obviously superior to inheritance simply in that you can only inherit
    once, but can compose many times. There are various stances one can take
    towards composing, from aggressive encapsulating of any functionality
    that lurks its head to lazily refactoring en masse. Note, however, that
    composition does not replace, or indeed affect, inheritance essentially:
    it merely replaces it in the context of one given class. Talking of
    composition merely _shifts_ the question of inheritance towards the
    classes actually implementing the encapsulated functionality. Now you
    may argue that, since through composition you grant the API user means
    to replace functionality in transparent manner, you can keep all your
    implementations of the encapsulated functionality locked tight. This
    would surely be a valid choice, and it may for any given case be
    justified or not -- but one thing's for sure and that's that you would
    be giving your customers less for their money by prohibiting re-use of
    code (unless you make it public throughout, which I don't suppose you'd
    advocate).

    You've been occasionally talking about "clean syntax", "few lines of
    code", suggesting your aim was at least partially at some kind of
    syntactic sugar. So let me state this: Java boilerplate code is GREAT.
    And in my view *any* request for modification of the JLS, the sole
    argument in favour of which is that it saves typing, does not deserve
    attention (nota bene: shorter syntax is not the same thing as greater
    clarity).
    What in my opinion is one of the greatest things about Java is that, at
    the basic level, the language features very few denizens: objects,
    primitives, classes, interfaces, functions, fields -- that's about it.
    With these basic entities, such high-level concepts as callbacks,
    closures or concurrent APIs can be built. Entirely transparently so. If
    someone wishes to see how it's done, they can, by simply reading the
    source code (except for native methods). They can reproduce it freely.
    No behind-the-scenes voodoo. Yes, that's it in two words: no voodoo.

    At least that's what it was like until they introduced the enhanced
    for-loop back in Tiger (I'm not entirely sure it was the first
    occurrence, but it's just an example, don't quote me on that). And I can
    only hope they won't get through with the closures stuff they're
    planning for 1.7. This to me is clearly a step in the wrong direction,
    because it /hides/ what's going on. It's voodoo. The enhanced for-loop
    takes an Iterable, initialises an iterator, and repeatedly calls next()
    while checking hasNext(). We know that because it's written in the
    specification. But the point is that nowhere can we see that in plain
    Java code anymore.
    Now don't get me wrong: the enhanced for-loop is really quite a pleasure
    to use, and even I, who am reluctant to it, have found myself making
    increasing use of it. But when it comes down to it and I am confronted
    with the choice between a short syntax where it's unclear what's going
    on and a longer syntax where you see precisely what's going on -- I'm
    always going to side with the latter. When you know what you're doing
    you can always assess that each bit of effort you provide, no matter how
    much of it is overall necessary, is productive; while in the opposite
    case you cannot tell whether it may be unproductive or, even worse,
    counter-productive.

    df.
    Daniele Futtorovic, Feb 19, 2008
    #8
  9. Daniel Pitts

    Daniel Pitts Guest

    Daniele Futtorovic wrote:
    > On 2008-02-19 23:10 +0100, Daniel Pitts allegedly wrote:
    >> Peter Duniho wrote:
    >>> On Tue, 19 Feb 2008 13:27:19 -0800, Daniel Pitts
    >>> <> wrote:
    >>>
    >>>> [...] I'm not saying that it is always and automatically bad. I
    >>>> guess my main point was that there are situations where, due to
    >>>> many language limitations, it is necessary to avoid a massive
    >>>> amounts of boiler-plate delegation code. If you had a convenient
    >>>> way (say one or two source lines) to "borrow" all/most
    >>>> implementation from another class, would you still feel that
    >>>> implementation inheritance is still necessary?
    >>>
    >>> I guess I can only at this point answer "it depends". It seems to
    >>> me that the current, widely-used implementation inheritance syntax
    >>> is pretty much just that: a convenient way to borrow implementation
    >>> from another class.

    >> Currently, inheritance of classes "borrows" both the implementation
    >> *and* interface. The thing is that interface and implementation are
    >> borrowed together, and you have to take extra steps if you only want
    >> the implementation or only the interface. I think it might be good
    >> to separate those concepts.
    >>>
    >>> I would have to see what this alternative syntax would look like to
    >>> answer more definitively, but it's not clear to me that it'd be
    >>> any different in practice from simply inheriting an implementation
    >>> directly (assuming that, as with interfaces, a "borrowing" class
    >>> still tests "true" for whether it "is" one of these "borrowed"
    >>> things...if that's not the case, then I'd say that's a glaring
    >>> omission of the proposal).

    >> If the interface "lives" separately from the implementation, then the
    >> borrow can choose to also borrow the interface (or some parent
    >> interface, or some composite interface).
    >>
    >>> Or, looking at the question from another angle, if it's okay to
    >>> "borrow" implementation from another class, what does it matter
    >>> whether it was borrowed in the form of inheritance or in the form
    >>> of a new type of composition that looks just like inheritance?

    >> Because the borrowing can be more pick-and-choose in the new way,
    >> instead of the all-or-nothing of inheritance. Also, there are times
    >> when your interface maps one-to-one to another class for a few
    >> methods. It could be easier to pick out those methods.
    >>>
    >>> I'm reading this in the Java newsgroup, and perhaps the
    >>> "comp.object" crowd has a more thorough academic understanding of
    >>> OOP practices and principles than I do. But I admit, based on what
    >>> you've written so far I'm not really clear on the distinction
    >>> between the way things are now and what you're suggesting they
    >>> could be, at least from a practical standpoint.

    >> I guess the main difference is the syntax, but I believe it adds
    >> flexibility too.
    >>

    >
    > /* The following deliberately sets itself strictly within the context of
    > the Java Programming Language, as it often most beneficial to have a
    > practical reference to focus the discussion. */
    >
    > It seems to me all practical examples you gave in this thread are
    > feasible with the current grammar of Java. There are two discrete
    > models, one for "borrowing" an interface and one for "borrowing" an
    > implementation; the first one is called implementing an interface and
    > the second one extending a class.
    > The practice of always providing both for all classes isn't ubiquitous,
    > or even widespread. But, while I grant this may cause you much grief on
    > diverse occasions, it is simply not an argument against the grammar of
    > Java, but only potentially against some of its uses.
    > On the subject of "borrowing an implementation", let me point out that
    > getting rid of protected modifiers, which you seem to aim at, would
    > effectively _force_ upon you _all_ the implementation that isn't public
    > -- so much for "borrowing can be more pick-and-choose".

    Anything that was "protected" is still a "public interface" to the
    inheritors. You can separate that out quite easily in all the
    circumstances I can think of.
    >
    > The use of composition in a given class is clearly a good idea and
    > obviously superior to inheritance simply in that you can only inherit
    > once, but can compose many times. There are various stances one can take
    > towards composing, from aggressive encapsulating of any functionality
    > that lurks its head to lazily refactoring en masse. Note, however, that
    > composition does not replace, or indeed affect, inheritance essentially:
    > it merely replaces it in the context of one given class. Talking of
    > composition merely _shifts_ the question of inheritance towards the
    > classes actually implementing the encapsulated functionality. Now you
    > may argue that, since through composition you grant the API user means
    > to replace functionality in transparent manner, you can keep all your
    > implementations of the encapsulated functionality locked tight. This
    > would surely be a valid choice, and it may for any given case be
    > justified or not -- but one thing's for sure and that's that you would
    > be giving your customers less for their money by prohibiting re-use of
    > code (unless you make it public throughout, which I don't suppose you'd
    > advocate).

    Since the "protected interface" is specific to an implementation, it
    should be called out differently IMO. As far as re-use goes, its
    important to limit re-use to things you expect to maintain in the
    future. You can still add the hooks to have extensibility in your code,
    enabling re-use. You just use a different pattern.
    >
    > You've been occasionally talking about "clean syntax", "few lines of
    > code", suggesting your aim was at least partially at some kind of
    > syntactic sugar. So let me state this: Java boilerplate code is GREAT.
    > And in my view *any* request for modification of the JLS, the sole
    > argument in favour of which is that it saves typing, does not deserve
    > attention (nota bene: shorter syntax is not the same thing as greater
    > clarity).

    I agree short/clever != clear, and this is not in the context of Java,
    despite the fact that I posted to cljp :)
    The syntax would be explicit and compact. Having not thought greatly
    into it. "MyFoo extends Foo {}" might become "MyFoo implements Foo { Foo
    foo; delegate "*" to foo; }

    Yes, its a little more typing, but you can replace that "*" with more
    specific names, etc... Thats where you get the pick-and-choose. It
    also allows inversion-of-control in the inheritance structure. Think "I
    want a MyFoo that extends FooBar, and I want another MyFoo that extends
    FooLish".

    > What in my opinion is one of the greatest things about Java is that, at
    > the basic level, the language features very few denizens: objects,
    > primitives, classes, interfaces, functions, fields -- that's about it.
    > With these basic entities, such high-level concepts as callbacks,
    > closures or concurrent APIs can be built. Entirely transparently so. If
    > someone wishes to see how it's done, they can, by simply reading the
    > source code (except for native methods). They can reproduce it freely.
    > No behind-the-scenes voodoo. Yes, that's it in two words: no voodoo.

    I agree with that. I'm not suggesting modifying Java, it would have to
    be another (possibly not-yet-existent) language.
    >
    > At least that's what it was like until they introduced the enhanced
    > for-loop back in Tiger (I'm not entirely sure it was the first
    > occurrence, but it's just an example, don't quote me on that). And I can
    > only hope they won't get through with the closures stuff they're
    > planning for 1.7. This to me is clearly a step in the wrong direction,
    > because it /hides/ what's going on. It's voodoo. The enhanced for-loop
    > takes an Iterable, initialises an iterator, and repeatedly calls next()
    > while checking hasNext(). We know that because it's written in the
    > specification. But the point is that nowhere can we see that in plain
    > Java code anymore.
    > Now don't get me wrong: the enhanced for-loop is really quite a pleasure
    > to use, and even I, who am reluctant to it, have found myself making
    > increasing use of it. But when it comes down to it and I am confronted
    > with the choice between a short syntax where it's unclear what's going
    > on and a longer syntax where you see precisely what's going on -- I'm
    > always going to side with the latter. When you know what you're doing
    > you can always assess that each bit of effort you provide, no matter how
    > much of it is overall necessary, is productive; while in the opposite
    > case you cannot tell whether it may be unproductive or, even worse,
    > counter-productive.

    True, and hopefully the "example" syntax I use above helps to show that
    I'm actually exposing more information rather than less. The "delegate"
    keyword would expose exactly which methods (by name or whatever) are
    being exposed.
    >
    > df.
    >


    Thanks (everyone) for the feedback so far. Even if it appear(s/ed) that
    I already made up my mind, it is something that I'm working out for
    myself, but want feedback to help confirm or deny my suspicions.


    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 20, 2008
    #9
  10. Daniele Futtorovic wrote:
    ....
    > With these basic entities, such high-level concepts as callbacks,
    > closures or concurrent APIs can be built. Entirely transparently so. If
    > someone wishes to see how it's done, they can, by simply reading the
    > source code (except for native methods). They can reproduce it freely.
    > No behind-the-scenes voodoo. Yes, that's it in two words: no voodoo.


    I've heard the "no voodoo" argument many times before, initially from
    people telling me why assembly languages were better than Fortran or
    Algol. Later, procedural languages were better than OO, because you can
    see exactly what function will be invoked, no virtual call voodoo.

    The increasing semantic gap between what the programmer writes and
    what the processor does has been a major theme of programming language
    development. The effect has been to greatly increase the effectiveness
    of programmers by automating a lot of details.

    What's different this time? Does Java really have *exactly* the right
    amount of voodoo, so that adding any more will take it past the current
    sweet spot?

    > At least that's what it was like until they introduced the enhanced
    > for-loop back in Tiger (I'm not entirely sure it was the first
    > occurrence, but it's just an example, don't quote me on that).


    I like the enhanced for-loop. If I just want to do something to every
    element in a collection an enhanced for-loop expresses my intent more
    directly and clearly than an Iterator idiom.

    Patricia
    Patricia Shanahan, Feb 20, 2008
    #10
  11. Patricia Shanahan <> writes:

    > To make this a bit more specific, consider ArrayList. It implements a
    > series of interfaces. Those describe the general behavior its callers
    > can depend on: it's a list, it has fast random access, it can be cloned
    > and serialized, and it has an Iterator.
    >
    > In addition, it extends AbstractList. That seems to me to be part of its
    > implementation, and not something I would use in my code. And yet, a
    > class outside java.util could declare:
    >
    > AbstractList<String> someList = new ArrayList<String>();
    >
    > It might be advantageous to split AbstractList, for example to provide
    > different implementations depending on whether the list has fast random
    > access. That cannot be done, because of the public nature of the uses of
    > AbstractList.


    Agreed.
    I wouldn't mind a language where implementation inheritance wasn't public,
    i.e., your type only consists of interfaces. If you extend another class,
    you also implements its interfaces, but the extended class is not part
    of your type.

    And I would also like an easy way to create a composition, e.g.,

    class Foo implements Bar(b) {
    private Bar barbarbar implements Bar; // or delegates Bar
    public Foo(int i) {
    super(i);
    this.barbarbar = new Bar(i);
    }
    //...
    }

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Feb 20, 2008
    #11
  12. On 2008-02-19 12:08:17 -0600, Daniel Pitts
    <> said:

    > My main point is that classes should use composition to gain behavior,
    > possibly with an easy mechanism for delegation. The *only* thing that
    > should be automatically inherited should be the interface. This
    > eliminates the need for (and usefulness of) the "protected" access modifier.


    Polymorphism is a good thing, and the use of interfaces to achieve
    polymorphism should be encouraged in Java. On the other hand, there
    are times when inheritance of implementation is -- pleasant.

    The standard Observer is a common enough example. Observable classes
    need to be able to register and notify observers. We can create a
    non-polymorphic class that provides this behavior:

    public class Subject {
    private List<Observer> observers = ArrayList<Observer>();
    public void register(Observer o) {observers.add(o);}
    public void notify() {
    for (Observer o : observers)
    o.update();
    }
    }

    Now any observable can inherit this class and enjoy the implementation
    of register and notify. Note that there is no polymorphism involved,
    or intended. We simply want the implementation.

    Of course the creators of Java were too wimpy to add true multiple
    inheritance. So by inheriting Subject, we use up the one and only
    inheritance slot for our observable class. That's a shame. If Java
    had true multiple inheritance then we'd be able to mix-in simple
    implementations like this, with other classes.

    As things stand, it is probably best to use composition to bring
    Subject into the observable, and use delegation to call the register
    and notify functions. But not because polymorphic interfaces are always
    better; rather because Java was crippled by the decision to turn
    multiple inheritance into the bogey man.
    --
    Robert C. Martin (Uncle Bob)  | email:
    Object Mentor Inc.            | blog:  www.butunclebob.com
    The Agile Transition Experts  | web:   www.objectmentor.com
    800-338-6716                  |
    Robert Martin, Feb 20, 2008
    #12
  13. On 2008-02-19 15:27:19 -0600, Daniel Pitts
    <> said:

    > My thoughts are that it should be *easy* to "borrow" implementation
    > from another object, without using inheritance but instead using
    > composition. To borrow your Container example: Say you have
    > MyContainer which implements the Container interface, and delegates
    > (with as clean a syntax as possible) most of its behavior to another
    > Container instance. You don't have to re-implement the containment
    > behavior.


    True, but you DO have to write all the delegating functions. Ick. Why
    should I have to write a bunch of brain-dead delegation functions every
    time I want to reuse some nice piece of implementation.

    It would be trivial to add language feature that did
    composition-and-delegation for you. It might look like this:

    class MyContainer composes SomeContainer {
    ...
    }

    This would create a hidden instance variable for SomeContainer, and
    automatically write delegation functions in MyContainer.

    Indeed, you might be able to compose more than one class. Let's say
    you wanted to have a contaier that was observable:

    class MyContainer composes SomeContainer, Subject {
    ...
    }

    How cool would this be! Automatic reuse through composition!!!

    There is a name for this feature.

    It's called Multiple Inheritance.

    --
    Robert C. Martin (Uncle Bob)  | email:
    Object Mentor Inc.            | blog:  www.butunclebob.com
    The Agile Transition Experts  | web:   www.objectmentor.com
    800-338-6716                  |
    Robert Martin, Feb 20, 2008
    #13
  14. On 2008-02-19 16:05:59 -0600, Patricia Shanahan <> said:
    >
    > I think the big question is what gets exposed to users of the borrowing
    > class.
    >
    > To make this a bit more specific, consider ArrayList. It implements a
    > series of interfaces. Those describe the general behavior its callers
    > can depend on: it's a list, it has fast random access, it can be cloned
    > and serialized, and it has an Iterator.
    >
    > In addition, it extends AbstractList. That seems to me to be part of its
    > implementation, and not something I would use in my code. And yet, a
    > class outside java.util could declare:
    >
    > AbstractList<String> someList = new ArrayList<String>();
    >
    > It might be advantageous to split AbstractList, for example to provide
    > different implementations depending on whether the list has fast random
    > access. That cannot be done, because of the public nature of the uses of
    > AbstractList.


    This is the reason that C++ has private inheritance. A privately
    inherited base class is inaccessible to any users or further subclasses.


    --
    Robert C. Martin (Uncle Bob)  | email:
    Object Mentor Inc.            | blog:  www.butunclebob.com
    The Agile Transition Experts  | web:   www.objectmentor.com
    800-338-6716                  |
    Robert Martin, Feb 20, 2008
    #14
  15. On 2008-02-20 00:15:44 -0600, Lasse Reichstein Nielsen <> said:

    > I wouldn't mind a language where implementation inheritance wasn't public,
    > i.e., your type only consists of interfaces. If you extend another class,
    > you also implements its interfaces, but the extended class is not part
    > of your type.


    You mean like in C++?

    class MyContainer : private SomeContainer {
    ....
    }

    >
    > And I would also like an easy way to create a composition, e.g.,
    >
    > class Foo implements Bar(b) {
    > private Bar barbarbar implements Bar; // or delegates Bar
    > public Foo(int i) {
    > super(i);
    > this.barbarbar = new Bar(i);
    > }
    > //...
    > }


    If you think about that a bit longer, you'll realize that an easy way
    to create composition IS inheritance. Or rather, inheritance is an
    easy way to create composition.

    Every method of the component gets redeclared in the composer. When
    those methods are called on the composer, the component's
    implementation is invoked.

    Now change the words composer to base, and component to derivative and
    you'll see the sentence is true.

    Perhaps what you are after is a way to make sure that the composer
    cannot be cast (explicitly or implicitly) to the component. That's
    what private inheritance gives you.

    I conclude from this that we'd all be happy if Java had multiple
    inheritance and private inheritance.

    ;-)

    --
    Robert C. Martin (Uncle Bob)  | email:
    Object Mentor Inc.            | blog:  www.butunclebob.com
    The Agile Transition Experts  | web:   www.objectmentor.com
    800-338-6716                  |
    Robert Martin, Feb 20, 2008
    #15
  16. Robert Martin wrote:
    > If you think about that a bit longer, you'll realize that an easy way to
    > create composition IS inheritance. Or rather, inheritance is an easy
    > way to create composition.
    >
    > Every method of the component gets redeclared in the composer. When
    > those methods are called on the composer, the component's implementation
    > is invoked.
    >
    > Now change the words composer to base, and component to derivative and
    > you'll see the sentence is true.
    >
    > Perhaps what you are after is a way to make sure that the composer
    > cannot be cast (explicitly or implicitly) to the component. That's what
    > private inheritance gives you.
    >
    > I conclude from this that we'd all be happy if Java had multiple
    > inheritance and private inheritance.
    >
    > ;-)
    >


    I disagree. Inheritance and interfaces a la Java have one important
    distinction: interfaces introduce no implicit implementation of methods.
    Since Java does not support multiple inheritance implementation
    inheritance is too limited for many use cases. C++ supports MI but in a
    very disturbed way (although I was quite happy with it when it was
    introduced into the language I have learned to really hate it). The
    issues of virtual bases and multiple down-cast paths leading to
    different implementations of the same function signature are painful. It
    is unclear how any implementation of multiple implementation inheritance
    could circumvent these issues.

    The advantage of the Java interface concept is that a class implementing
    an interface (and not extending any other class than Object) will have
    to explicitly define how the interface methods are implemented. If it
    extends multiple interfaces with shared function signatures the seaming
    ambiguity is resolved at the class level itself.

    Unfortunately Java lacks a simple way of expressing interface
    delegation. I would have loved something like:

    interface I1
    {
    public void f1();
    public void f2();
    public void f3();
    }

    class C1 implements I1
    {
    public void f1() { /*...*/ }
    public void f2() { /*...*/ }
    public void f3() { /*...*/ }
    }

    class C2 implements I1, I2
    {
    private C1 c1a;
    private C1 c1b;
    public I1() { return c1a != null ? c1a : c1b; } /* NOT SUPPORTED */
    public void f2() { /* THIS IS AN OVERRULE IMPLEMENTATION */ }
    }

    where the constructor-like syntax of the 'public I1() { /*...*/}'
    notation implies that all methods declared in I1 and not declared in C2
    or I2 are implicitly implemented such that given a C2 reference c2
    calling c2.f1() is equal to c2.I1().f2().


    This syntax would be ideal for implementing partial delegations of
    interfaces with many methods when writing wrapper classes (the JDBC or
    Servlet interfaces anyone?).

    Would such syntax/semantics exist I would be happy to drop
    implementation inheritance in most places.

    Kind regards,

    Silvio Bierman
    Silvio Bierman, Feb 20, 2008
    #16
  17. On 2008-02-20 02:47 +0100, Patricia Shanahan allegedly wrote:
    > Daniele Futtorovic wrote: ....
    >> With these basic entities, such high-level concepts as callbacks,
    >> closures or concurrent APIs can be built. Entirely transparently
    >> so. If someone wishes to see how it's done, they can, by simply
    >> reading the source code (except for native methods). They can
    >> reproduce it freely. No behind-the-scenes voodoo. Yes, that's it in
    >> two words: no voodoo.

    >
    > I've heard the "no voodoo" argument many times before, initially from
    > people telling me why assembly languages were better than Fortran or
    > Algol. Later, procedural languages were better than OO, because you
    > can see exactly what function will be invoked, no virtual call
    > voodoo.
    >
    > The increasing semantic gap between what the programmer writes and
    > what the processor does has been a major theme of programming
    > language development. The effect has been to greatly increase the
    > effectiveness of programmers by automating a lot of details.
    >
    > What's different this time? Does Java really have *exactly* the right
    > amount of voodoo, so that adding any more will take it past the
    > current sweet spot?


    You're right, so maybe the emphasis shouldn't be on /how much/ voodoo,
    but on /how/ voodoo. The point would be to find a minimal set of
    building blocks, of basic entities, which encapsulate the voodoo, and to
    keep the set minimal. Especially not to inflate it with synonyms which
    make no semantical addition.

    >> At least that's what it was like until they introduced the enhanced
    >> for-loop back in Tiger (I'm not entirely sure it was the first
    >> occurrence, but it's just an example, don't quote me on that).

    >
    > I like the enhanced for-loop. If I just want to do something to every
    > element in a collection an enhanced for-loop expresses my intent
    > more directly and clearly than an Iterator idiom.


    Not functionally so, for functionally, you are using an Iterator. What's
    happened is that, from the point of view of the code, you've introduced
    a new entity which, though linguistically distinct, makes no semantic
    addition. It's a synonym.

    df.
    Daniele Futtorovic, Feb 20, 2008
    #17
  18. Daniel Pitts

    H. S. Lahman Guest

    Responding to Pitts...

    > I was thinking about it, and it seems to me that implementation
    > inheritance is a convenience that leads to bad design and mistakes. By
    > convenience, I mean that often a programmer will design the an interface
    > and the implementation together in one source unit (e.g. a class).
    > Alternatively, you can define a separate interface (lets call it IFoo)
    > in one source unit, and an implementation (FooImpl). FooImpl is *also*
    > an interface in many languages, it just happens to have the associated
    > implementation.


    I think it is important to distinguish between simple implementation
    inheritance and overrides of implementation inheritance. Overrides have
    proven to be a Really Bad Idea if one cares about maintainability.

    However, simple implementation inheritance is almost always benign. To
    create a situation where maintenance of the generalization can break
    existing clients requires a large and complicated generalization, which
    should make one look for delegation solutions in the first place. Also,
    the foot-shooting examples I've seen with simple implementation
    inheritance can be attacked on other design grounds.

    The problem is that every OOPL I know that supports implementation
    inheritance also supports overrides because the underlying jump table
    mechanism is the same. But just because a language supports a feature
    doesn't mean one needs to use it. I think an OOA/D methodological
    prohibition of using overrides is sufficient.

    > So far, not that big of a deal. The convolution comes when you add in
    > access modifiers. For instance, in Java you can mark methods/fields as
    > private, protected, package-private, or public. Now, you have up to 4
    > interfaces to the implementation. Only certain code units can see some
    > of the interfaces, but managing that contract becomes troublesome,
    > especially for the "protected" interface, as many programmers don't
    > design their classes for inheritance but the class gets used that way.


    IMO, the public/private stuff found in OOPLs is just syntactic sugar
    that saves the developer some keystrokes at the cost of potentially
    introducing foot-shooting. There is nothing these qualifiers provide
    that one could not do with different developer-defined interfaces and
    associating specific clients with specific interfaces. [In the
    translation MDA profile I use for OOA, those qualifiers are not
    available. A full code generator has no problem generating correct code
    without them.]

    [FWIW, I think Protected is a kludge and the only place I would use it
    is to support a unit test harness -- for which it is very convenient.
    But let's not go there...]

    > To me, polymorphic behavior is important, and "implementation sharing"
    > is a very useful convenience. I think that they are often co-mingled
    > concepts that should be separated. I have a few ideas on how I might do
    > this, at the language level, but I wanted to see if my above thoughts on
    > the subject stirred any interesting discussions.


    I agree they are different things. But I think one can prevent them from
    becoming co-mingled in a detrimental way methodologically. The OOPLs
    /implement/ OOA/D; methodologies drive OOA/D.

    [Note that the OOPLs do much more egregious things, such as combining
    message and method, simply because they are 3GLs. But those things are
    rendered harmless by getting the OOA/D right.]

    > My main point is that classes should use composition to gain behavior,
    > possibly with an easy mechanism for delegation. The *only* thing that
    > should be automatically inherited should be the interface. This
    > eliminates the need for (and usefulness of) the "protected" access
    > modifier.


    Unrestrained composition has its own set of problems as it can trash
    object cohesion.


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

    H. S. Lahman

    Pathfinder Solutions
    http://www.pathfindermda.com
    blog: http://pathfinderpeople.blogs.com/hslahman
    "Model-Based Translation: The Next Step in Agile Development". Email
    for your copy.
    Pathfinder is hiring:
    http://www.pathfindermda.com/about_us/careers_pos3.php.
    (888)OOA-PATH
    H. S. Lahman, Feb 20, 2008
    #18
  19. Daniele Futtorovic wrote:
    > On 2008-02-20 02:47 +0100, Patricia Shanahan allegedly wrote:

    ....
    >> What's different this time? Does Java really have *exactly* the right
    >> amount of voodoo, so that adding any more will take it past the
    >> current sweet spot?

    >
    >
    > You're right, so maybe the emphasis shouldn't be on /how much/ voodoo,
    > but on /how/ voodoo. The point would be to find a minimal set of
    > building blocks, of basic entities, which encapsulate the voodoo, and to
    > keep the set minimal. Especially not to inflate it with synonyms which
    > make no semantical addition.


    All you really need is a Turing machine. Its basic entities are a state
    machine, a current state, and a tape with a single read/write head. Or,
    to be a bit more practical, consider the original MIPS instruction set.
    Its assembly language is very simple, with few basic entities.

    However, I find it far easier to express my programs in Java than in any
    assembly language.

    >> I like the enhanced for-loop. If I just want to do something to every
    >> element in a collection an enhanced for-loop expresses my intent
    >> more directly and clearly than an Iterator idiom.

    >
    >
    > Not functionally so, for functionally, you are using an Iterator. What's
    > happened is that, from the point of view of the code, you've introduced
    > a new entity which, though linguistically distinct, makes no semantic
    > addition. It's a synonym.


    Sure. Even assembly languages add new entities which, though
    linguistically distinct, make no semantic addition. For example, "nop"
    is often provided as a mnemonic, but mapped to some existing operation
    that does nothing. What's wrong with that, as long as it makes the
    resulting programs a clearer expression of the programmer's intent?

    Patricia
    Patricia Shanahan, Feb 20, 2008
    #19
  20. Robert Martin wrote:
    >
    > True, but you DO have to write all the delegating functions. Ick.
    > Why should I have to write a bunch of brain-dead delegation
    > functions
    > every time I want to reuse some nice piece of implementation.
    >
    > It would be trivial to add language feature that did
    > composition-and-delegation for you. It might look like this:
    >
    > class MyContainer composes SomeContainer {
    > ...
    > }
    >
    > This would create a hidden instance variable for SomeContainer, and
    > automatically write delegation functions in MyContainer.


    It would also be trivial for an IDE to generate the delegation methods
    for you, and no languages changes are required for that.
    Mike Schilling, Feb 21, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,120
    Martijn van Steenbergen
    Dec 21, 2003
  2. Maciek Zywno
    Replies:
    0
    Views:
    366
    Maciek Zywno
    Feb 19, 2004
  3. Michael Tsang
    Replies:
    32
    Views:
    1,086
    Richard Bos
    Mar 1, 2010
  4. Michael Tsang
    Replies:
    54
    Views:
    1,174
    Phil Carmody
    Mar 30, 2010
  5. sanket
    Replies:
    7
    Views:
    984
    Tsung
    Nov 3, 2011
Loading...

Share This Page