Why can't a class extend an enum?

后端 未结 5 1830
死守一世寂寞
死守一世寂寞 2021-01-17 10:18

I am wondering why in the Java language a class cannot extend an enum.

I\'m not talking about an enum extending an enum<

相关标签:
5条回答
  • 2021-01-17 10:50

    The whole point of an enum is to create a closed set of possible values. This makes it easier to reason about what a value of that enum type is -- easier for you the programmer, and also easier for the compiler (this closedness is what lets it handle enums efficiently in switches, for instance). Allowing a class to extend an enum would open up the set of possible values; at that point, what does the enum buy you that a regular class wouldn't?

    0 讨论(0)
  • 2021-01-17 10:51

    May I also add that we can emulate Extensible enums using interfaces.

    From Joshua Bloch's brilliant book

    http://books.google.com/books?id=ka2VUBqHiWkC&pg=PA165&lpg=PA165&dq=mulate+extensible+enums+with+interfaces&source=bl&ots=yYKhIho1R0&sig=vd6xgrOcKr4Xhb6JDAdkxLO278A&hl=en&sa=X&ei=XyBgUqLVD8-v4APE6YGABg&ved=0CDAQ6AEwAQ#v=onepage&q=mulate%20extensible%20enums%20with%20interfaces&f=false

    or

    http://jtechies.blogspot.com/2012/07/item-34-emulate-extensible-enums-with.html

    0 讨论(0)
  • 2021-01-17 10:56

    I think an answer to why they did it this way comes from this question:

    In your example, how would you instantiate a MyClass? Enums are never explicitly instantiated (via a new MyEnum()) by the user. You'd have to do something like MyClass.ASD but not sure how that would work.

    Basically, I don't know what syntax would work for your proposed addition. Which is probably why they made them final etc...

    EDIT ADDED

    If the author of the original Enum planned ahead (unlikely), and you are not worried too much abut thread safety, you could do something like this: (BTW, I'd probably scream at anybody who actually did this in production code, YMMV)

    public enum ExtendibleEnum {
    
       FOO, BAR, ZXC;
    
       private Runnable anotherMethodRunme;  // exact Interface will vary, I picked an easy one
                               // this is what gets "injected" by your other class
    
       public void setAnotherMethodRunMe(Runnable r) {  // inject here
          anotherMethodRunme= r;
       }
    
       public void anotherMethod() {  // and this behavior gets changed
          anotherMethodRunme.run();
       }
    }
    
    0 讨论(0)
  • 2021-01-17 11:01

    You can't extend an enum. They are implicitly final. From JLS § 8.9:

    An enum type is implicitly final unless it contains at least one enum constant that has a class body.

    Also, from JLS §8.1.4 - Superclasses and Subclasses:

    It is a compile-time error if the ClassType names the class Enum or any invocation of it.

    Basically an enum is an enumerated set of pre-defined constants. Due to this, the language allows you to use enums in switch-cases. By allowing to extend them, wouldn't make them eligible type for switch-cases, for example. Apart from that, an instance of the class or other enum extending the enum would be then also be an instance of the enum you extend. That breaks the purpose of enums basically.

    0 讨论(0)
  • 2021-01-17 11:03

    In ancient days of pre Java 1.5 you would probably do enums like this:

    public class MyEnum {
    
    public static final MyEnum ASD = new MyEnum(5);
    public static final MyEnum QWE = new MyEnum(3);
    public static final MyEnum ZXC = new MyEnum(7);
    
    private int number;
    
    private MyEnum(int number) {
        this.number = number;
    }
    
    public int myMethod() {
        return this.number;
        }
    
    } 
    

    There are two important things about this figure:

    • private constructor that will not allow to instantiate the class from outside
    • actual "enum" values are stored in static fields

    Even if it's not final when you'll extend it, you'll realize that compiler requires an explicit constructor, that in other turn is required to call super constructor which is impossible since that one is private. Another problem is that the static fields in super class still store object of that super class not your extending one. I think that this could be an explanation.

    0 讨论(0)
提交回复
热议问题