Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / May 2007

Tip: Looking for answers? Try searching our database.

Subclassing EnumSet to add an interface?

Thread view: 
Eric Smith - 12 May 2007 07:41 GMT
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
Mike Schilling - 12 May 2007 08:11 GMT
> 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
[quoted text clipped - 22 lines]
>                  ^
>  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.)
Eric Smith - 12 May 2007 10:58 GMT
Mike Schilling
> You're not specifying a constructor, so one is being created for you, which
> looks like
[quoted text clipped - 3 lines]
>         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%.
Richard Reynolds - 12 May 2007 12:02 GMT
> Mike Schilling
>> You're not specifying a constructor, so one is being created for you,
[quoted text clipped - 18 lines]
> 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.
Lew - 12 May 2007 18:35 GMT
>> Mike Schilling
>>> You're not specifying a constructor, so one is being created for you,
[quoted text clipped - 20 lines]
> 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."

Signature

Lew

Eric Smith - 12 May 2007 20:33 GMT
> As Joshua Bloch advised in /Effective Java/, "prefer composition to inheritance."

Even when you only want to add one simple method?
Lew - 13 May 2007 17:24 GMT
>> 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.

Signature

Lew

Eric Smith - 14 May 2007 00:15 GMT
> 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 - 14 May 2007 00:29 GMT
> 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 - 12 May 2007 20:33 GMT
> 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
Tom Hawtin - 12 May 2007 12:22 GMT
> 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
Eric Smith - 12 May 2007 20:54 GMT
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%.

> 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.
Lew - 13 May 2007 17:26 GMT
> I wrote:
>> I never cease to be amazed at how often the standard Java
[quoted text clipped - 6 lines]
> 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.

Signature

Lew

Eric Smith - 14 May 2007 00:19 GMT
> 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.
Tom Hawtin - 14 May 2007 02:14 GMT
> 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
Eric Smith - 15 May 2007 07:42 GMT
> 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
Patricia Shanahan - 15 May 2007 10:17 GMT
...
> 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.
[quoted text clipped - 4 lines]
>
> 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
Tom Hawtin - 15 May 2007 14:00 GMT
>> 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
[quoted text clipped - 3 lines]
> 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
Eric Smith - 17 May 2007 03:42 GMT
> 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?

> 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.
Lasse Reichstein Nielsen - 12 May 2007 14:26 GMT
> 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
Signature

Lasse Reichstein Nielsen  -  lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
 'Faith without judgement merely degrades the spirit divine.'



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.