2

I have multiple enum's that all have the same constructor and attributes, like this:

enum Enum1 {
    A(1,2),
    B(3,4);

    public int a, b;
    private Enum1(int a, int b) {
        this.a = a;
        this.b = b;
    }
}


enum Enum2 {
    C(6,7),
    D(8,9);

    public int a, b;
    private Enum1(int a, int b) {
        this.a = a;
        this.b = b;
    }
}

and so on... Unfortunately Enum1 and Enum2 already extend Enum, so it isn't possible to write a superclass they could extend. Is there another way to archive this?

Update: here comes a "real-world" example. Think of a classic rpg, where you have items, armour, weapons etc. which give you a bonus.

enum Weapon {
    SWORD(3,0,2),
    AXE_OF_HEALTH(3,4,1);

    // bonus for those weapons
    public int strength, health, defense;
    private Weapon(int strength, int health, int defense) {
        this.strength = strength;
        this.health = health;
        this.defense = defense;
    }
}

enum Armour {
    SHIELD(3,1,6),
    BOOTS(0,4,1);

    // bonus
    public int strength, health, defense;
    private Weapon(int strength, int health, int defense) {
        this.strength = strength;
        this.health = health;
        this.defense = defense;
    }
}
user28061
  • 354
  • 1
  • 4
  • 14
  • 2
    Why do you have separate `Enum` classes for enums which have pretty much the same data? Why can't `C` or `D` go in `Enum1`? I think giving us the concrete scenario might help in reaching closer to the real solution. – Sanjay T. Sharma Jul 10 '12 at 09:40
  • See [Java extend enum](http://stackoverflow.com/questions/1414755/java-extend-enum). – Lion Jul 10 '12 at 09:47
  • 1
    Sorry to say it but this design doesn't look right. Of course YMMV but those attributes are better off on "individual" shields, boots etc. I'd recommend having "items" which have a type field, which in turn would be an enum *without* attributes. Of course there are other ways of doing it but please make the information available as part of class attributes (driven from configuration) rather than making them "hard-coded". – Sanjay T. Sharma Jul 10 '12 at 09:54
  • @SanjayT.Sharma So you would do this: [see pastebin](http://pastebin.com/QdipY9n3). Then how could I get e.g. a random SUFFIX? – user28061 Jul 10 '12 at 10:23
  • 1
    @user28061: No, still doesn't look right. Why are you so fixated on using an "enum"? Why can't those entities be a different class on it's own (e.g. `GameEntity` as opposed to an `enum`? Tying yourself up with an enum for stuff (game entities) which usually is pretty dynamic, has behaviour and is part of a logical hierarchy (i.e. might need inheritance features) is a big mistake IMO. Start with regular classes and code up stuff which addresses the immediate concern (working game) rather than fighting with enum limitations. :) – Sanjay T. Sharma Jul 10 '12 at 18:33
  • @SanjayT.Sharma I came across this issue several times, it is not limited to this rpg example. What I like about enums is that the are fast/easy to compare. – user28061 Jul 10 '12 at 22:28
  • @user28061: Unfortunately that doesn't justify their usage pretty much everywhere IMO. "Fast and easy" comparisons are a side-effect of enums (since each enum instance is a singleton) but not the reason for using enums. YMMV. – Sanjay T. Sharma Jul 11 '12 at 05:19

4 Answers4

3

You have to combine them (or not if thats not a good idea)

enum Enum1 {
    A(1,2),
    B(3,4),
    C(6,7),
    D(8,9);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1
No, you can't extend enums in Java.

As Peter mentioned you can combine them.

My be this can help you.

amicngh
  • 7,831
  • 3
  • 35
  • 54
1

Enums extend Enum. They cannot also extend something else. However, they can implement interfaces.

You can make them both implement a common interface, and put your getA(), getB() methods on the interface.

Rob Trickey
  • 1,301
  • 11
  • 13
0

You can try to use this and than add flag to your enum:



    public class ExtendetFlags : Attribute
    {
        #region Properties

        /// 
        /// Holds the flagvalue for a value in an enum.
        /// 
        public string FlagValue { get; protected set; }

        #endregion

        #region Constructor

        /// 
        /// Constructor used to init a FlagValue Attribute
        /// 
        /// 
        public ExtendetFlags(string value)
        {
            this.FlagValue = value;
        }

        #endregion
    }

    public static class ExtendetFlagsGet
    {
        /// 
        /// Will get the string value for a given enums value, this will
        /// only work if you assign the FlagValue attribute to
        /// the items in your enum.
        /// 
        /// 
        /// 
        public static string GetFlagValue(this Enum value)
        {
            // Get the type
            Type type = value.GetType();

            // Get fieldinfo for this type
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // Get the stringvalue attributes
            ExtendetFlags[] attribs = fieldInfo.GetCustomAttributes(
                typeof(ExtendetFlags), false) as ExtendetFlags[];

            // Return the first if there was a match.
            return attribs.Length > 0 ? attribs[0].FlagValue : null;
        }
    }


Using is simple:


`            [ExtendetFlags("test1")]
            Application = 1,
            [ExtendetFlags("test2")]
            Service = 2
`