Can enums be subclassed to add new elements?

前端 未结 15 1991
臣服心动
臣服心动 2020-11-22 12:02

I want to take an existing enum and add more elements to it as follows:

enum A {a,b,c}

enum B extends A {d}

/*B is {a,b,c,d}*/

Is this po

15条回答
  •  情深已故
    2020-11-22 12:18

    This is how I enhance the enum inheritance pattern with runtime check in static initializer. The BaseKind#checkEnumExtender checks that "extending" enum declares all the values of the base enum in exactly the same way so #name() and #ordinal() remain fully compatible.

    There is still copy-paste involved for declaring values but the program fails fast if somebody added or modified a value in the base class without updating extending ones.

    Common behavior for different enums extending each other:

    public interface Kind {
      /**
       * Let's say we want some additional member.
       */
      String description() ;
    
      /**
       * Standard {@code Enum} method.
       */
      String name() ;
    
      /**
       * Standard {@code Enum} method.
       */
      int ordinal() ;
    }
    

    Base enum, with verifying method:

    public enum BaseKind implements Kind {
    
      FIRST( "First" ),
      SECOND( "Second" ),
    
      ;
    
      private final String description ;
    
      public String description() {
        return description ;
      }
    
      private BaseKind( final String description ) {
        this.description = description ;
      }
    
      public static void checkEnumExtender(
          final Kind[] baseValues,
          final Kind[] extendingValues
      ) {
        if( extendingValues.length < baseValues.length ) {
          throw new IncorrectExtensionError( "Only " + extendingValues.length + " values against "
              + baseValues.length + " base values" ) ;
        }
        for( int i = 0 ; i < baseValues.length ; i ++ ) {
          final Kind baseValue = baseValues[ i ] ;
          final Kind extendingValue = extendingValues[ i ] ;
          if( baseValue.ordinal() != extendingValue.ordinal() ) {
            throw new IncorrectExtensionError( "Base ordinal " + baseValue.ordinal()
                + " doesn't match with " + extendingValue.ordinal() ) ;
          }
          if( ! baseValue.name().equals( extendingValue.name() ) ) {
            throw new IncorrectExtensionError( "Base name[ " + i + "] " + baseValue.name()
                + " doesn't match with " + extendingValue.name() ) ;
          }
          if( ! baseValue.description().equals( extendingValue.description() ) ) {
            throw new IncorrectExtensionError( "Description[ " + i + "] " + baseValue.description()
                + " doesn't match with " + extendingValue.description() ) ;
          }
        }
      }
    
    
      public static class IncorrectExtensionError extends Error {
        public IncorrectExtensionError( final String s ) {
          super( s ) ;
        }
      }
    
    }
    

    Extension sample:

    public enum ExtendingKind implements Kind {
      FIRST( BaseKind.FIRST ),
      SECOND( BaseKind.SECOND ),
      THIRD( "Third" ),
      ;
    
      private final String description ;
    
      public String description() {
        return description ;
      }
    
      ExtendingKind( final BaseKind baseKind ) {
        this.description = baseKind.description() ;
      }
    
      ExtendingKind( final String description ) {
        this.description = description ;
      }
    
    }
    

提交回复
热议问题