extending enum

R

Roedy Green

Has anyone figured out how you extend an enum, e.g.

1. a class like the base but with more enum constants.

2. a class like the base but with more methods on each enum constant.


--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
C

Chris Smith

Roedy Green said:
Has anyone figured out how you extend an enum, e.g.

1. a class like the base but with more enum constants.

2. a class like the base but with more methods on each enum constant.

Nope, neither of these are possible.

Regarding #1:

If you think about it, inheritance goes the wrong direction for adding
enum constants. A subclass needs to meet the requirements for a
superclass, plus add additional capabilities or constraints. The most
important facet of an enum type is that it is limited to a finite set of
values. A subtype of an enumeration would need to keep that constraint
plus add more... so it might make sense for a subtype of an enum to
define a limited subset of the possible values in its supertype... but
it breaks type safety for a subtype to add more possible contents.

In order to sensibly implement an expansion of possibilities for enum
constants, something opposite to subtyping would be needed. You'd need
implicit conversion from the base type to the derivative type, but NOT
from the derivative type to the base type. Logically, this wouldn't fit
with the 'extends' keyword... you'd need to add a new keyword, like
'expands', just for that purpose. This also really screws with method
overload resolution, which depends on the possibility of various
implicit conversions.

IMO, it was quite sensible of Sun to avoid this can of worms and refuse
to provide a mechanism for adding possibilities to an enum. We just
don't need that kind of complexity in the type system.

Regarding #2: You're asking for something that unequivocally isn't
possible in Java; that is, the ability to write code that modifies the
methods or fields of a class that is not even aware of your code. You
can't do this, for the same reason that I can't write a class A that
adds methods to existing objects of class B.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim Tyler

Chris Smith said:
Has anyone figured out how you extend an enum, e.g.

1. a class like the base but with more enum constants.

2. a class like the base but with more methods on each enum constant.

Nope, neither of these are possible.

Regarding #1:

If you think about it, inheritance goes the wrong direction for adding
enum constants. A subclass needs to meet the requirements for a
superclass, plus add additional capabilities or constraints. The most
important facet of an enum type is that it is limited to a finite set of
values. A subtype of an enumeration would need to keep that constraint
plus add more... [...]

IMO, that's a curious perspective on what inheritance is about.

In biology, inherintance is a process of making modified derivatives.

In computer science too - as far as I can tell - inherited classes
can violate existing constraints as well as impose new ones.
 
C

Chris Smith

Tim Tyler said:
If you think about it, inheritance goes the wrong direction for adding
enum constants. A subclass needs to meet the requirements for a
superclass, plus add additional capabilities or constraints. The most
important facet of an enum type is that it is limited to a finite set of
values. A subtype of an enumeration would need to keep that constraint
plus add more... [...]

IMO, that's a curious perspective on what inheritance is about.

In biology, inherintance is a process of making modified derivatives.

In computer science too - as far as I can tell - inherited classes
can violate existing constraints as well as impose new ones.

That perspective is implicit in seeing API elements as representing
contracts. The client of an object may be unaware whether it has an
instance of a specific subclass or a more general superclass, but it
expects that the API contracts will be fulfilled in either case. The
use of an enum return value, for instance, implies a contract that only
one of a specific, well-known, finite set of values will be included.
Returning some other value is basically violating a postcondition.

Perhaps a different way of explaining would be better.

Generally speaking, casting is required when a conversion may fail
because the value is not compatible with the target type. If an enum B
"extends" enum A in the proposed feature, then it is safe to convert
from A to B. The set of possible values of B is a superset of the
possible values of A, so the A to B conversion is widening and should
not require a cast. Conversely, converting from B to A is narrowing and
should require a cast.

This is backwards from the type relationship normally implied by the
"extends" keyword. If class B extends class A, then the A to B
conversion is narrowing, and the B to A conversion is widening.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
L

Lasse Reichstein Nielsen

Tim Tyler said:
IMO, that's a curious perspective on what inheritance is about.

In biology, inherintance is a process of making modified derivatives.

Inheritance is the passing of traits to an offspring. The creation
of the offspring is done by reproduction.

Biology uses prototype based inheritance, not class based :)
In computer science too - as far as I can tell - inherited classes
can violate existing constraints as well as impose new ones.

In class based OO, inheritance is a means for passing traits from one
class to a subclass. The creation of a subclass is done by
specialisation.

The operative concept here is "specialization". The relation between a
superclass and its subclass is one of specializtion/generalization
(which is also what UML calls it). Specialization means that an
instance of the subclass *is* an instance of the superclass, and
should be usable everywhere an instance of the superclass is. In
particular, it should satisfy all the requirements of the superclass,
and should *not* violate existing constraints (whether people do it is
a different matter).

A related concept is that of sub-*typing*. One type is s sub-type of
another, if the set of values of the former is a subset of the set of
values of the latter (rough definition, but it works in most cases).
A class defines a type with the set of instances of itself and of its
subclasses as values. A subclass therefore trivially defines a
subtype.

The idea with enums is to create a type with a fixed, finite, number
of values. The traditional finite types are void and boolean (with 0
and 2 values respectively). Extending an enum in a subclass, as RG's
#1 request ("a class like a base but with more enum constants"), would
make the sub-type contain *more* elements that the super-type -
effectively making the super-enum the sub-type. That's why it's the
wrong way around.

/L
 
T

Tim Tyler

Chris Smith said:
If you think about it, inheritance goes the wrong direction for adding
enum constants. A subclass needs to meet the requirements for a
superclass, plus add additional capabilities or constraints. The most
important facet of an enum type is that it is limited to a finite set of
values. A subtype of an enumeration would need to keep that constraint
plus add more... [...]

IMO, that's a curious perspective on what inheritance is about.

In biology, inherintance is a process of making modified derivatives.

In computer science too - as far as I can tell - inherited classes
can violate existing constraints as well as impose new ones.

That perspective is implicit in seeing API elements as representing
contracts. The client of an object may be unaware whether it has an
instance of a specific subclass or a more general superclass, but it
expects that the API contracts will be fulfilled in either case. The
use of an enum return value, for instance, implies a contract that only
one of a specific, well-known, finite set of values will be included.
Returning some other value is basically violating a postcondition.

I guess I think that contracts should be specified by, well, contracts.

Java doesn't have much support for contracts. It has an "assert"
statement - but there's no notion of method pre- or post-
conditions - and subclasses don't inherit much in the way of an
explicit contract from their parents - they can do mostly whatver
they like - short of overriding things that are final.

There /may/ be an "implied contract" associated with some class.

Since Java doesn't offer much support for contracts, the whole notion
seems rather vague and wooly.
 
J

jan V

I guess I think that contracts should be specified by, well, contracts.
Java doesn't have much support for contracts.

From en Eiffel perspective, that's true. But from a Java perspective, "we"
treat method signatures as the next best thing (and I agree with you, it's
pretty basic compared to Eiffel style contracts).
 
T

Tim Tyler

jan V said:
From en Eiffel perspective, that's true. But from a Java perspective, "we"
treat method signatures as the next best thing (and I agree with you, it's
pretty basic compared to Eiffel style contracts).

Method signatures enforce you to have the same return type as
any method with the same signature in the superclass.

These days, they force you to have the same argument types - iff
the method is marked with @Override.

Final methods stop you from implementing something with the same
signature in derived classes.

An interface is a sort of contract about methods - if you implement
interface I, you need to have methods x(), y() and z().

However, that seems to be about it. If method signatures specify
a contract, it seems to be one that doesn't say very much.
 
T

Thomas Hawtin

Roedy said:
Has anyone figured out how you extend an enum, e.g.

1. a class like the base but with more enum constants.

2. a class like the base but with more methods on each enum constant.

To try and be helpful rather than explain why you are evil...


If you want have all the benefits of enumerations, but still be able to
divide them, then interfaces can help.

interface Day {
DayOfWeek toDayOfWeek();
boolean sameDay(Day other);
}
enum DayOfWeek implements Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
public Day toDay() {
return this;
}
public boolean sameDay(Day other) {
return other != null && this == other.toDayOfWeek();
}
}
enum Weekday implements Day {
MONDAY (DayOfWeek.MONDAY ),
TUESDAY (DayOfWeek.TUESDAY ),
WEDNESDAY(DayOfWeek.WEDNESDAY),
THURSDAY (DayOfWeek.THURSDAY ),
FRIDAY (DayOfWeek.FRIDAY );

private final DayOfWeek dayOfWeek;
private Weekday(DayOfWeek dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
public DayOfWeek toDayk() {
return dayOfWeek;
}
public boolean sameDay(Day other) {
return other != null && dayOfWeek == other.toDayOfWeek();
}
}

Perhaps Enum should have been an interface itself, so abstract base
classes could be shared.

Tom Hawtin
 
G

George Cherry

Roedy Green said:
Has anyone figured out how you extend an enum, e.g.

1. a class like the base but with more enum constants.

Why would you want to do this? A fixed set of named constants
is what enum offers. The trouble with using ints for a"fixed"
number of named constants is that the number of named
constants is NOT fixed (except in the enumeration pattern).
A subclass of an enum type (if there were such a thing, which
there isn't) would destroy the FIXED number of named constants
guarantee of the enum type.
2. a class like the base but with more methods on each enum constant.

This would not harm the guarantee of a fixed number of named
constants.
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes

There are serious initiatives to impeach Bush. Veterans
for Peace has an impeachment petition on-line:

http://www.veteransforpeace.org/impeachment/petition2.htm
 
R

Roedy Green

If you think about it, inheritance goes the wrong direction for adding
enum constants.

Right, but that still does not get rid of the need for an enum based
on another. To use them, they can be treated as totally separate
beasts.


For example, I was considering converting int style enums to enums.
However there are three sets of enum methods, common, for sender only,
and for receiver only. I CAN'T give everyone all the methods without
dragging in all kinds of unwanted code.

With ints, this is no problem, though the code lacks organisation.

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
R

Roedy Green

Regarding #2: You're asking for something that unequivocally isn't
possible in Java; that is, the ability to write code that modifies the
methods or fields of a class that is not even aware of your code. You
can't do this, for the same reason that I can't write a class A that
adds methods to existing objects of class B.

Imagine an implementation like this for my two requests:

It decomplies the code of the base class, inserts your code in the
proper places and recompiles giving a totally new class with methods
from the base plus your added methods.

There is no extend going on, just code borrowing and a bit of
syntactic sugar to make it look superficially like an extension.


--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
R

Roedy Green

Generally speaking, casting is required when a conversion may fail
because the value is not compatible with the target type. If an enum B
"extends" enum A in the proposed feature, then it is safe to convert
from A to B. The set of possible values of B is a superset of the
possible values of A, so the A to B conversion is widening and should
not require a cast. Conversely, converting from B to A is narrowing and
should require a cast.

One way to maintain the contract would be to have added enum constants
having to be derived from existing ones, so from the point of view of
the base class, there are no new types, just subflavours.

The derived enum would be free to treat its constants all
individually, or possibly even collectively with enum constants from
the base.

You could then describe something like a Linnaen phyla/species tree
with various enums to cover different parts of it.

This of this as like enums for specialists where everything outside
their purview is lumped into general categories, where there are
specific ones for their fields of interest.


--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
R

Roedy Green

There /may/ be an "implied contract" associated with some class.

There is an implied contract on an enum variable that it will be null
or one of the enum constants. There are no other possible values.

If you invented a way to allow other values, existing enum code would
break.


--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
R

Roedy Green

Why would you want to do this?

Generally the more money you spend the wider your choices.
You have a base set of options, and the deluxe of options.

You could handle it by tagging the deluxe options as deluxe, but there
are great hunks of your code where only the basic options apply. You
don't want the deluxe possibilities even mentioned cluttering up the
logic.

Examples might be options for the free vs pay version of a program.

options when run as applet vs standalone vs JAWS.

options for domestic vs foreign in a security suite.

Perhaps another way of making the request is to create an enum with a
restricted subset of some bigger enum.

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
T

Tim Tyler

Roedy Green said:
There is an implied contract on an enum variable that it will be null
or one of the enum constants. There are no other possible values.

If you invented a way to allow other values, existing enum code would
break.

The only way I can think of doing what you are asking is to do it
dynamically.

I.e. use reflection, to find the fields of then enumeration, and
then generate the class that implements the enumeration with
the additional fields - and any other classes that use it.

This sounds like a right pain to me :-|

You are probably better off not solving this problem - and instead
finding another way around it.
 
Joined
Jun 25, 2011
Messages
1
Reaction score
0
Extended Enums Petition

Hi all,

the missing inheritance of enumerations is a recurring (and pretty much arbitrary) limitation of the Java language, and for many instances a royal pain in the neck (especially in combination with annotations).

We are joining forces now to propose at least a basic support for enumeration extendability for the upcoming Java-8 edition.

Please help us in moving the Extended-Enum petition forward, and vote for us at http://www.extended-enums.org - this would be really minimal change with a maximum of impact and transcendence!

cheers and many thnx,

Chris
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top