Java equivalent of MI for augmenting base of a hierarchy

Discussion in 'Java' started by David Bolen, Aug 21, 2003.

  1. David Bolen

    David Bolen Guest

    I was wondering what might be a typical approach in Java to handle a
    case where I might have used multiple inheritance in languages that
    supported it; specifically that of wanting to augment a base class and
    its child classes without having to replicate code in the child
    classes.

    In the simplest case, let's say that I have a simple hierarchy like:

    Player
    |
    Dealer

    Now I come along and I wish to have an augmented Player class, say one
    that is cognizant of a GUI subsystem. So what I'd like to end up with
    is, conceptually, a new hierarchy of:

    Player
    |
    +----+----+
    | |
    Dealer GUIPlayer
    | |
    +----+----+
    |
    GUIDealer

    In an MI language, I would just inherit from both GUIPlayer and Dealer
    and I'd have my GUIDealer - likely without writing any actual body
    code in GUIDealer.

    In Java, its simple enough for GUIPlayer to extend Player, but
    obviously I can't MI from Dealer. And since Dealer is a concrete
    class I can't use it as an interface. Even if I were to extract
    Dealer into an interface (which would get me the equivalence I might
    want with respect to method parameters) I'd still have to implement
    the interface twice, in Dealer and GUIDealer, even though the
    implementations would be identical.

    At the moment I'm looking at doing delegation with an internal Dealer
    object inside of GUIDealer. It still requires that I ensure I keep
    GUIDealer manually in sync with the Dealer interface (so extracting
    Dealer to an interface would make that easier to ensure in an
    automated way), but I have to keep writing the code to delegate each
    method.

    Is there a more Java-centric way to handle this sort of problem?

    Thanks.

    -- David
     
    David Bolen, Aug 21, 2003
    #1
    1. Advertising

  2. David Bolen

    James Wilson Guest

    David Bolen wrote:

    > I was wondering what might be a typical approach in Java to handle a
    > case where I might have used multiple inheritance in languages that
    > supported it; specifically that of wanting to augment a base class and
    > its child classes without having to replicate code in the child
    > classes.
    >
    > In the simplest case, let's say that I have a simple hierarchy like:
    >
    > Player
    > |
    > Dealer
    >
    > Now I come along and I wish to have an augmented Player class, say one
    > that is cognizant of a GUI subsystem. So what I'd like to end up with
    > is, conceptually, a new hierarchy of:
    >
    > Player
    > |
    > +----+----+
    > | |
    > Dealer GUIPlayer
    > | |
    > +----+----+
    > |
    > GUIDealer
    >
    > In an MI language, I would just inherit from both GUIPlayer and Dealer
    > and I'd have my GUIDealer - likely without writing any actual body
    > code in GUIDealer.
    >
    > In Java, its simple enough for GUIPlayer to extend Player, but
    > obviously I can't MI from Dealer. And since Dealer is a concrete
    > class I can't use it as an interface. Even if I were to extract
    > Dealer into an interface (which would get me the equivalence I might
    > want with respect to method parameters) I'd still have to implement
    > the interface twice, in Dealer and GUIDealer, even though the
    > implementations would be identical.
    >
    > At the moment I'm looking at doing delegation with an internal Dealer
    > object inside of GUIDealer. It still requires that I ensure I keep
    > GUIDealer manually in sync with the Dealer interface (so extracting
    > Dealer to an interface would make that easier to ensure in an
    > automated way), but I have to keep writing the code to delegate each
    > method.


    Read "Effective Java Progamming Language Guide" by Joshua Block. Item's
    14, 16, 17, 34 speek specifically to your questions.

    >
    > Is there a more Java-centric way to handle this sort of problem?
    >
    > Thanks.
    >
    > -- David
    >

    I think you're on the right track though. Composition is a good way.

    public interface Player
    methods of the interface

    public interface Dealer extends Player
    extra methods of the interface

    public interface GUIPlayer extends Player
    extra methods of the interface

    public interface GUIDealer extends Dealer, GUIPlayer
    extra methods of the interface


    And then create concrete implementations of each of these
    interfaces.

    Hope this helps,

    James
     
    James Wilson, Aug 25, 2003
    #2
    1. Advertising

  3. David Bolen

    David Bolen Guest

    James Wilson <> writes:

    > I think you're on the right track though. Composition is a good way.
    >
    > public interface Player
    > methods of the interface
    >
    > public interface Dealer extends Player
    > extra methods of the interface
    >
    > public interface GUIPlayer extends Player
    > extra methods of the interface
    >
    > public interface GUIDealer extends Dealer, GUIPlayer
    > extra methods of the interface
    >
    >
    > And then create concrete implementations of each of these
    > interfaces.


    Yeah, that's what I figured - unfortunately in this example I
    duplicate even more effort (implementations) than just single
    inheriting from GUIPlayer in that I have to duplicate both the
    GUIPlayer and Dealer logic in GUIDealer. If I inherit from GUIPlayer
    than I just have to reimplement the original Dealer/Player logic
    differences.

    The rub is that the only practical between GUIDealer and Dealer is the
    difference created between GUIPlayer and Player - so other than
    wanting to inherit that difference, any other code I write as part of
    GUIDealer is duplication that I have to maintain.

    Thanks for the info (and book reference) though.

    -- David
     
    David Bolen, Aug 26, 2003
    #3
  4. David Bolen wrote:
    > James Wilson <> writes:
    >
    >
    >>I think you're on the right track though. Composition is a good way.
    >>
    >>public interface Player
    >> methods of the interface
    >>
    >>public interface Dealer extends Player
    >> extra methods of the interface
    >>
    >>public interface GUIPlayer extends Player
    >> extra methods of the interface
    >>
    >>public interface GUIDealer extends Dealer, GUIPlayer
    >> extra methods of the interface
    >>
    >>
    >>And then create concrete implementations of each of these
    >>interfaces.

    >
    >
    > Yeah, that's what I figured - unfortunately in this example I
    > duplicate even more effort (implementations) than just single
    > inheriting from GUIPlayer in that I have to duplicate both the
    > GUIPlayer and Dealer logic in GUIDealer. If I inherit from GUIPlayer
    > than I just have to reimplement the original Dealer/Player logic
    > differences.
    >
    > The rub is that the only practical between GUIDealer and Dealer is the
    > difference created between GUIPlayer and Player - so other than
    > wanting to inherit that difference, any other code I write as part of
    > GUIDealer is duplication that I have to maintain.


    I came late to this discussion, so likely I'm missing something, but it
    sure seems like Dealer is a role that a Player can have more than it is
    a specific type of Player. The design is more loosely coupled if Dealer
    does not extend Player but instead is associated with a Player. Among
    the advantages this would provide is that there would be no need for
    different kinds of Dealers in parallel with different kinds of Players
    (i.e. you could do away with GUIDealer altogether).

    Also, interfaces are very useful in many situations, but not so useful
    if there is no room for alternative implementations. In this particular
    case, if Player is a class then it can expose a package-private API for
    a seperate Dealer object to use, but if it is an interface then all its
    methods are implictly public.


    John Bollinger
     
    John C. Bollinger, Aug 26, 2003
    #4
  5. David Bolen

    David Bolen Guest

    "John C. Bollinger" <> writes:

    > I came late to this discussion, so likely I'm missing something, but
    > it sure seems like Dealer is a role that a Player can have more than
    > it is a specific type of Player. The design is more loosely coupled
    > if Dealer does not extend Player but instead is associated with a
    > Player. Among the advantages this would provide is that there would
    > be no need for different kinds of Dealers in parallel with different
    > kinds of Players (i.e. you could do away with GUIDealer altogether).


    As with any design, I'd have to agree that there are multiple ways to
    build the original class hierarchy, but I did find it more natural to
    consider Dealer to have a fairly classic "is a" relationship with
    Player. A Dealer is just another form of a Player which overrides
    some characteristics (such as presentation of hand). I suppose I
    could have encapsulated presentation of hand into a separate role sort
    of object, but then I end up with two tightly coupled object
    effectively needing to share state (the hand) which otherwise just
    belongs to the Player. I guess I could argue either way though. The
    net is still though that I only burped in the Java implementation due
    to lack of MI (of implementation).

    I do have additional Rules and Behavior classes that function in more
    of a role design, where any player object can be associated with
    (composed of) rules that it obeys and with behavior that it exhibits
    in reacting to events/queries. But Dealer felt more natural as a
    subclass in the original (pre-GUI) implementation.

    > Also, interfaces are very useful in many situations, but not so useful
    > if there is no room for alternative implementations. In this
    > particular case, if Player is a class then it can expose a
    > package-private API for a seperate Dealer object to use, but if it is
    > an interface then all its methods are implictly public.


    All its methods, or just those methods that are needed to meet the
    interface? Presumably Player could implement the interface, but still
    offer other package-private API methods for use by other objects, right?

    -- David
     
    David Bolen, Aug 28, 2003
    #5
    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. Dan Wilkin
    Replies:
    11
    Views:
    1,434
    Dan Wilkin
    Mar 5, 2004
  2. John J. Lee

    Changing base class of a big hierarchy

    John J. Lee, Aug 3, 2003, in forum: Python
    Replies:
    7
    Views:
    367
    John J. Lee
    Aug 5, 2003
  3. disappearedng

    Augmenting functions

    disappearedng, Nov 13, 2008, in forum: Javascript
    Replies:
    6
    Views:
    93
    John G Harris
    Nov 14, 2008
  4. optimistx

    Augmenting ECMA-262 specs: crazy idea?

    optimistx, Nov 6, 2009, in forum: Javascript
    Replies:
    8
    Views:
    169
    Dmitry A. Soshnikov
    Nov 9, 2009
  5. Ryan Chan

    Augmenting Types

    Ryan Chan, Jan 3, 2010, in forum: Javascript
    Replies:
    113
    Views:
    779
    Jorge
    Jan 9, 2010
Loading...

Share This Page