Subclassing EnumSet to add an interface?

Discussion in 'Java' started by Eric Smith, May 12, 2007.

  1. Eric Smith

    Eric Smith Guest

    I'd like to create a subclass of EnumSet to implement the Comparable
    interface (using my own arbitrary ordering, so that I can use the
    subclass as a key in a dictionary), but I can't seem to figure
    out how to do it.

    I tried:

    import java.util.EnumSet;

    public abstract class Foo<E extends Enum<E>> extends EnumSet<E>
    implements Comparable<Foo>
    {
    public int compareTo (Foo o)
    {
    return 1; // dummy value for now
    }
    }


    The compiler says:

    Foo.java:3: cannot find symbol
    symbol : constructor EnumSet()
    location: class java.util.EnumSet<E>
    public abstract class Foo<E extends Enum<E>> extends EnumSet<E>
    ^
    1 error


    I don't understand why it thinks there should be an EnumSet()
    constructor, since I'm subclassing it as an abstract class.
    Any hints or suggestions?

    Thanks!
    Eric
     
    Eric Smith, May 12, 2007
    #1
    1. Advertising

  2. "Eric Smith" <> wrote in message
    news:...
    > I'd like to create a subclass of EnumSet to implement the Comparable
    > interface (using my own arbitrary ordering, so that I can use the
    > subclass as a key in a dictionary), but I can't seem to figure
    > out how to do it.
    >
    > I tried:
    >
    > import java.util.EnumSet;
    >
    > public abstract class Foo<E extends Enum<E>> extends EnumSet<E>
    > implements Comparable<Foo>
    > {
    > public int compareTo (Foo o)
    > {
    > return 1; // dummy value for now
    > }
    > }
    >
    >
    > The compiler says:
    >
    > Foo.java:3: cannot find symbol
    > symbol : constructor EnumSet()
    > location: class java.util.EnumSet<E>
    > public abstract class Foo<E extends Enum<E>> extends EnumSet<E>
    > ^
    > 1 error


    You're not specifying a constructor, so one is being created for you, which
    looks like

    public Foo()
    {
    super();
    }

    The compiler is complaining that the constructor "super()" is attempting to
    call doesn't exist. In fact, since EnumSet has no public constructors, it
    cannot be subclassed (other than, perhaps, within its package.)
     
    Mike Schilling, May 12, 2007
    #2
    1. Advertising

  3. Eric Smith

    Eric Smith Guest

    Mike Schilling
    > You're not specifying a constructor, so one is being created for you, which
    > looks like
    >
    > public Foo()
    > {
    > super();
    > }


    Yes, I had tried doing that explicitly as well.

    > In fact, since EnumSet has no public constructors, it
    > cannot be subclassed (other than, perhaps, within its package.)


    Thanks, I was afraid that might be the case but wasn't sure.

    Ugh. I'll have to write my own EnumSet class.

    I never cease to be amazed at how often the standard Java
    classes do 95% of what I want, but *cannot* be coerced into
    letting me implement that last 5%.
     
    Eric Smith, May 12, 2007
    #3
  4. "Eric Smith" <> wrote in message
    news:...
    > Mike Schilling
    >> You're not specifying a constructor, so one is being created for you,
    >> which
    >> looks like
    >>
    >> public Foo()
    >> {
    >> super();
    >> }

    >
    > Yes, I had tried doing that explicitly as well.
    >
    >> In fact, since EnumSet has no public constructors, it
    >> cannot be subclassed (other than, perhaps, within its package.)

    >
    > Thanks, I was afraid that might be the case but wasn't sure.
    >
    > Ugh. I'll have to write my own EnumSet class.
    >
    > I never cease to be amazed at how often the standard Java
    > classes do 95% of what I want, but *cannot* be coerced into
    > letting me implement that last 5%.


    Could you write your own class that implements Comparable and just delegates
    the EumSet methods to a contained EnumSet class? maybe that's what you meant
    anyway?
    Richard.
     
    Richard Reynolds, May 12, 2007
    #4
  5. Eric Smith

    Tom Hawtin Guest

    Eric Smith wrote:
    >
    > Ugh. I'll have to write my own EnumSet class.


    No. Just use Comparator rather than Comparable.

    > I never cease to be amazed at how often the standard Java
    > classes do 95% of what I want, but *cannot* be coerced into
    > letting me implement that last 5%.


    You just have to use it correctly.

    Tom Hawtin
     
    Tom Hawtin, May 12, 2007
    #5
  6. Eric Smith <> writes:

    > I'd like to create a subclass of EnumSet to implement the Comparable
    > interface (using my own arbitrary ordering, so that I can use the
    > subclass as a key in a dictionary), but I can't seem to figure
    > out how to do it.


    As others have pointed out, EnumSet cannot be subclassed.

    Two approaches spring to mind, if all you need are keys based on
    sets of enum values:

    Make an adapter key object containing the EnumSet:

    class MyDictionaryKey<T extends Enum>
    implements Comparable<MyDictionaryKey<T>> {
    private final EnumSet<T> enumSet;
    public MyDictionaryKey(EnumSet<T> enumSet) {
    this.enumSet = enumSet;
    }
    public EnumSet<T> getEnumSet() {
    return enumSet;
    }
    public int compareTo(MyDictionaryKey<T> other) {
    /// ...your impl
    }
    }

    and use it for keys in your dictionary.

    Or, create a Comparator<EnumSet<MyEnum>> and use a dictionary
    that allows a comparator for the keys.

    /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, May 12, 2007
    #6
  7. Eric Smith

    Lew Guest

    Richard Reynolds wrote:
    > "Eric Smith" <> wrote in message
    > news:...
    >> Mike Schilling
    >>> You're not specifying a constructor, so one is being created for you,
    >>> which
    >>> looks like
    >>>
    >>> public Foo()
    >>> {
    >>> super();
    >>> }

    >> Yes, I had tried doing that explicitly as well.
    >>
    >>> In fact, since EnumSet has no public constructors, it
    >>> cannot be subclassed (other than, perhaps, within its package.)

    >> Thanks, I was afraid that might be the case but wasn't sure.
    >>
    >> Ugh. I'll have to write my own EnumSet class.
    >>
    >> I never cease to be amazed at how often the standard Java
    >> classes do 95% of what I want, but *cannot* be coerced into
    >> letting me implement that last 5%.

    >
    > Could you write your own class that implements Comparable and just delegates
    > the EumSet methods to a contained EnumSet class? maybe that's what you meant
    > anyway?


    As Joshua Bloch advised in /Effective Java/, "prefer composition to inheritance."

    --
    Lew
     
    Lew, May 12, 2007
    #7
  8. Eric Smith

    Eric Smith Guest

    "Richard Reynolds" <> writes:
    > Could you write your own class that implements Comparable and just delegates
    > the EumSet methods to a contained EnumSet class? maybe that's what you meant
    > anyway?


    If I'm going to the trouble of implementing it myself, I'm going to
    implement it in terms of bitmaps stored as ints or longs, to make the
    compareTo function efficent.

    But thanks for the idea! Using delegation like that may well solve
    other problems I face.

    Eric
     
    Eric Smith, May 12, 2007
    #8
  9. Eric Smith

    Eric Smith Guest

    Lew <> writes:
    > As Joshua Bloch advised in /Effective Java/, "prefer composition to inheritance."


    Even when you only want to add one simple method?
     
    Eric Smith, May 12, 2007
    #9
  10. Eric Smith

    Eric Smith Guest

    I wrote:
    > I never cease to be amazed at how often the standard Java
    > classes do 95% of what I want, but *cannot* be coerced into
    > letting me implement that last 5%.


    Tom Hawtin wrote:
    > You just have to use it correctly.


    I originally learned object-oriented programming in Smalltalk.
    Perhaps Smalltalk taught me to do things incorrectly, though
    at the time I didn't seem to have trouble with it.
     
    Eric Smith, May 12, 2007
    #10
  11. Eric Smith

    Lew Guest

    Eric Smith wrote:
    > Lew <> writes:
    >> As Joshua Bloch advised in /Effective Java/, "prefer composition to inheritance."

    >
    > Even when you only want to add one simple method?


    Perhaps especially then. But the advice is "prefer", not "insist on". Why
    don't you read the book for his detailed reasoning?

    The decision isn't based on whether you're only going "to add one simple
    method". First off, the complexity of the method is completely immaterial.
    The decision is based on your object model. Your object model is based on
    your analysis. If your analysis says "B /is-a/n A", then the modeled B
    inherits from the modeled A. If it doesn't, then B does not inherit from A.
    Simple. Number of methods not a factor.

    Correctness is not simply a matter of counting. Think carefully about your model.

    --
    Lew
     
    Lew, May 13, 2007
    #11
  12. Eric Smith

    Lew Guest

    Eric Smith wrote:
    > I wrote:
    >> I never cease to be amazed at how often the standard Java
    >> classes do 95% of what I want, but *cannot* be coerced into
    >> letting me implement that last 5%.

    >
    > Tom Hawtin wrote:
    >> You just have to use it correctly.

    >
    > I originally learned object-oriented programming in Smalltalk.
    > Perhaps Smalltalk taught me to do things incorrectly, though
    > at the time I didn't seem to have trouble with it.


    Apples and oranges. Completely misses the point.

    The comment was about using the Java classes correctly, not about using
    "object-oriented programming" correctly.

    --
    Lew
     
    Lew, May 13, 2007
    #12
  13. Eric Smith

    Eric Smith Guest

    Lew <> writes:
    > If your analysis says "B /is-a/n A",
    > then the modeled B inherits from the modeled A. If it doesn't, then B
    > does not inherit from A. Simple. Number of methods not a factor.


    The analysis did say "B is an A". Specifically, it said "B is an A
    that also does one extra thing."

    > Correctness is not simply a matter of counting. Think carefully about
    > your model.


    I have thought carefully about it. Condescenion is not helpful.
     
    Eric Smith, May 14, 2007
    #13
  14. Eric Smith

    Eric Smith Guest

    Lew wrote:
    > Apples and oranges. Completely misses the point.
    >
    > The comment was about using the Java classes correctly, not about
    > using "object-oriented programming" correctly.


    So what I've learned from you in this thread is:

    1) I should use subclassing only when "A is a B" (as it was in my example)
    2) I'm using Java wrong

    You haven't explained how to reconcile those two points, given
    that my complaint was in fact about Java not letting me subclass
    a provided cass.
     
    Eric Smith, May 14, 2007
    #14
  15. Eric Smith

    Eric Smith Guest

    Lew wrote:
    > The decision isn't based on whether you're only going "to add one
    > simple method". First off, the complexity of the method is completely
    > immaterial. The decision is based on your object model. Your object
    > model is based on your analysis. If your analysis says "B /is-a/n A",
    > then the modeled B inherits from the modeled A. If it doesn't, then B
    > does not inherit from A. Simple. Number of methods not a factor.


    If A has a bunch of methods, and you need a B that has those methods
    plus one more, there is a high probability that "B is an A".
    Number of methods may not directly be a factor, but it's also not
    completely irrelevant.
     
    Eric Smith, May 14, 2007
    #15
  16. Eric Smith

    Tom Hawtin Guest

    Eric Smith wrote:
    >
    > 1) I should use subclassing only when "A is a B" (as it was in my example)


    Your analysis was poor. Does Foo need to be an EnumSet? Given that an
    instance of EnumSet does practically nothing that an AbstractSet does,
    it appears not. Then there is Comparable. Must that be implemented by
    the same class as that which contains the Set? It seems they can easily
    be kept separate (and therefore probably should).

    > 2) I'm using Java wrong


    Clearly.

    Tom Hawtin
     
    Tom Hawtin, May 14, 2007
    #16
  17. Eric Smith

    Eric Smith Guest

    Tom Hawtin <> writes:
    > Your analysis was poor. Does Foo need to be an EnumSet? Given that an
    > instance of EnumSet does practically nothing that an AbstractSet does,
    > it appears not.


    How did you determine that? The reason I wanted to use an EnumSet was
    in fact that my requirements involve Foo doing nearly everything an
    EnumSet does. Specifically, I need to be able to construct various
    sets from Enum elements, add and remove Enum elements from the set, take
    the union of two sets (adding one to another), and determine whether a
    particular Enum is in the set. I don't really care in the least what
    an AbstractSet does.

    So in what sense was my analysis of my requirements for a Foo class
    "poor"?

    It may well be that my plan for *implementing" the Foo class in Java
    was poor, but that's a separate issue.

    > Then there is Comparable. Must that be implemented by
    > the same class as that which contains the Set? It seems they can
    > easily be kept separate (and therefore probably should).


    I originally had in mind to use the Foo in several situations, some
    of which required a Comparable (and not a separate Comparator). Since
    then I have found ways to avoid the need for Comparable.

    My point was that it seemed unreasonable for Java to deny me the
    ability to extend an EnumSet to add a small amount of new behavior.
    I can live with the fact that I can't do it, but no one has offered
    justification as to why such a limitation was a reasonable design
    choice. The fact there are other ways to do something isn't a
    good justification for introducing non-orthonality into a design.

    Eric
     
    Eric Smith, May 15, 2007
    #17
  18. Eric Smith wrote:
    ....
    > My point was that it seemed unreasonable for Java to deny me the
    > ability to extend an EnumSet to add a small amount of new behavior.
    > I can live with the fact that I can't do it, but no one has offered
    > justification as to why such a limitation was a reasonable design
    > choice. The fact there are other ways to do something isn't a
    > good justification for introducing non-orthonality into a design.
    >
    > Eric


    I think the real issue is the decision to use public static factory
    methods in class EnumSet rather than having a public constructor.

    The factory approach allows the base class to choose the actual class of
    the object at run time, based on the parameters. A public constructor
    leaves the actual class in the hands of the caller, through subclassing.

    Looking at its source code, EnumSet does take advantage of having
    control over the subclass. It uses different implementations depending
    on whether the Enum has no more than 64 elements. The RegularEnumSet
    implementation takes advantage of the bits fitting in a single long.
    JumboEnumSet uses an array of long.

    Patricia
     
    Patricia Shanahan, May 15, 2007
    #18
  19. Eric Smith

    Tom Hawtin Guest

    Eric Smith wrote:
    > Tom Hawtin <> writes:
    >> Your analysis was poor. Does Foo need to be an EnumSet? Given that an
    >> instance of EnumSet does practically nothing that an AbstractSet does,
    >> it appears not.

    >
    > How did you determine that?


    I read the API docs.

    > The reason I wanted to use an EnumSet was
    > in fact that my requirements involve Foo doing nearly everything an
    > EnumSet does. Specifically, I need to be able to construct various
    > sets from Enum elements, add and remove Enum elements from the set, take
    > the union of two sets (adding one to another), and determine whether a
    > particular Enum is in the set. I don't really care in the least what
    > an AbstractSet does.


    That's what a Set does, right?

    > So in what sense was my analysis of my requirements for a Foo class
    > "poor"?


    By claiming to require subclassing of a class that doesn't do anything
    interesting.

    > My point was that it seemed unreasonable for Java to deny me the
    > ability to extend an EnumSet to add a small amount of new behavior.
    > I can live with the fact that I can't do it, but no one has offered
    > justification as to why such a limitation was a reasonable design
    > choice. The fact there are other ways to do something isn't a
    > good justification for introducing non-orthonality into a design.


    Look at the documentation. EnumSet has little behaviour itself (over and
    above that of AbstractSet). It's not a useful class to subclass.

    For my money, I'd have made all the collection implementation classes
    package private, a bit like the implementations in Collections. Leaving
    them public 'bloats' the API, inheritance exposes implementation and
    selection of implementation is much easier with creation methods.

    Tom Hawtin
     
    Tom Hawtin, May 15, 2007
    #19
  20. Eric Smith

    Eric Smith Guest

    Tom Hawtin wrote:
    > Your analysis was poor. Does Foo need to be an EnumSet? Given that an
    > instance of EnumSet does practically nothing that an AbstractSet does,
    > it appears not.


    I wrote:
    > How did you determine that?


    Tom Hawtin wrote:
    > I read the API docs.


    You're confusing analysis of requirements with implementation.
    I determine what object behavior I required; the API docs were
    neither necessary nor sufficient to do so.

    Whether my requirements can be met by an implmentation using
    EnumSet is a different matter, and for reasons that have been
    explained in this thread, they cannot.
     
    Eric Smith, May 17, 2007
    #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. Roedy Green

    EnumSet, what the ?

    Roedy Green, Jul 8, 2005, in forum: Java
    Replies:
    6
    Views:
    1,944
    George Cherry
    Jul 9, 2005
  2. George Cherry

    EnumSet--what the...?

    George Cherry, Jul 9, 2005, in forum: Java
    Replies:
    0
    Views:
    2,397
    George Cherry
    Jul 9, 2005
  3. Roedy Green

    EnumSet Generics puzzle

    Roedy Green, Aug 18, 2005, in forum: Java
    Replies:
    11
    Views:
    1,595
    Thomas Hawtin
    Aug 22, 2005
  4. Ulrich Scholz

    EnumSet + contains: strange behavior

    Ulrich Scholz, May 31, 2006, in forum: Java
    Replies:
    10
    Views:
    1,693
    Christian Kaufhold
    Jun 4, 2006
  5. Roedy Green

    Enumset

    Roedy Green, Aug 31, 2007, in forum: Java
    Replies:
    10
    Views:
    1,354
    Lasse Reichstein Nielsen
    Sep 1, 2007
Loading...

Share This Page