28

I have an enum, let's call it A:

public enum A
{
    A,
    B
}

I have a function that takes an enum A:

public void functionA(A enumA)
{
    //do something
}

How can I create another enum, possibly call B that I can pass to functionA? Something like this?

public enum B
{
    C
}

functionA(B.C);

I know that you can't extend an enum, but what other options do I have available? What is the best way to achieve this?

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
user489041
  • 27,916
  • 55
  • 135
  • 204
  • 1
    What are you hoping to accomplish by doing this? The reason `functionA` takes an `A` parameter is because it specifically expects only those values. Suppose you could somehow trick it into taking another value from an extended enum. How would the function know what to do with it? – Karl Knechtel Jun 28 '11 at 18:43
  • 1
    Im trying to add a new enum that is similar to the existing one, but doesnt make sense to add the values too. I was hoping I wouldnt have to modify the function at all to handle it. – user489041 Jun 28 '11 at 18:44
  • 1
    Please be more specific. It would help to talk about what the function actually does, and what the actual enumeration values are, and why the new enumeration ought to be handled by the same function. – Karl Knechtel Jun 29 '11 at 02:14
  • 1
    possible duplicate of [Can enums be subclassed to add new elements?](http://stackoverflow.com/questions/1414755/can-enums-be-subclassed-to-add-new-elements) – Mike Nakis Mar 25 '15 at 13:27

4 Answers4

55

You can't.

Enum types are final by design.

The reason is that each enum type should have only the elements declared in the enum (as we can use them in a switch statement, for example), and this is not possible if you allow extending the type.

You might do something like this:

public interface MyInterface {
    // add all methods needed here
}

public enum A implements MyInterface {
    A, B;
    // implement the methods of MyInterface
}

public enum B implements MyInterface {
    C;
    // implement the methods of MyInterface
}

Note that it is not possible to do a switch with this interface, then. (Or in general have a switch with an object which could come from more than one enum).

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
  • If I can not, then what would be the best way to refactor it? – user489041 Jun 28 '11 at 18:42
  • @user489051: See my latest edit. Hmm, it is the same what Peter posted. – Paŭlo Ebermann Jun 28 '11 at 18:46
  • Does this remove my ability thought to switch on the enum? I suppose I would be switching on an interface now – user489041 Jun 28 '11 at 18:50
  • 1
    Yes, you **can't** do a `switch(x) { case A: case B: case C: }` if A, B and C are not defined in the same enum type. – Paŭlo Ebermann Jun 28 '11 at 19:06
  • I get an incompatible type error, looking for int, found I_Event. I_Event is the interface that both enums extend. – user489041 Jun 28 '11 at 19:09
  • You can not switch on anything else than integral types or enum types (or strings, with JDK 7). Your interface is not an enum type. – Paŭlo Ebermann Jun 28 '11 at 19:11
  • How do I make my interface a enum type? Right now, I just have an empty interface that both my enums implement. – user489041 Jun 28 '11 at 19:16
  • 1
    You can not. You can either have a single enum type (e.g. `enum A { A, B, C; }`), or multiple enum types, but for the latter one there is no switch statement. The switch statement requires that there is a **finite number of elements**, and this is contrary to you adding more enum values. – Paŭlo Ebermann Jun 28 '11 at 19:35
  • Ohhh... Gotcha. Looks like I cant have my cake and eat it too – user489041 Jun 28 '11 at 19:38
17

You can implement a common interface

interface I { }

enum A implements I {
   A, B
}
enum B implements I {
   C
}
public void functionA(I i) {
    //do something
}

obj.functionA(A.A);
obj.functionA(B.C);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 4
    Does this remove my ability to switch on the enum? – user489041 Jun 28 '11 at 18:51
  • 7
    @user489041, Instead of using a `switch` you can add a method to the interface `doSomething()` which you can call. Each method implements what you would put in the switch block. – Peter Lawrey Jun 28 '11 at 20:13
6

You cannot make Enums extend other Enums, but you can declare an interface which all your Enums can implement. The interface will have to include any methods you expect to invoke on your Enum values. Here is an example:

public class Question6511453 {
    public static void main(String[] args) {
        System.out.println(functionFoo(EnumA.FirstElem));
        System.out.println(functionFoo(EnumA.SecondElem));
        System.out.println(functionFoo(EnumB.ThirdElem));
    }

    private interface MyEnums {
        int ordinal();
    }

    private enum EnumA implements MyEnums {
        FirstElem,
        SecondElem
    }

    private enum EnumB implements MyEnums {
        ThirdElem
    }

    private static int functionFoo(MyEnums enumeration) {
        return enumeration.ordinal();
    }
}

The only problem with this solution is that it takes away your ability to use the Enum as you normally would like in switch statements, because the ordinals and values may not be unique anymore.

This should answer your question, but I doubt it will actually help you with your problem. :(

Richard Jessop
  • 897
  • 1
  • 12
  • 19
Jesse Webb
  • 43,135
  • 27
  • 106
  • 143
4

You should add item C to your enum A. If it's something unrelated and adding it doesn't make sense, functionA() probably shouldn't be the one to handle it.

ahans
  • 1,697
  • 12
  • 19