Java基础-----枚举类型

一.枚举类型的基础知识

1.1枚举类型的简单实现

enum Size{SMALL,MIDDLE,BIG}

1.2枚举类型的常用方法

    1.2.1一般方法

        

        打箭头的就是常用的一般方法,其中valueOf()方法会在编译器重载一次

    1.2.2特殊的方法

        枚举类型有两个比较特殊的静态方法 1.values()     2.valueOf(String s)

        其中,valueOf(String s)方法相比于上图中的valueOf()方法更加简便一点,返回枚举类型的具体实例

        values()方法则会返回此枚举类型的数组

for(Size size : Size.values()) {
			System.out.println("size : " + size);
		}

        但是,因为values()是编译器加入的,所以将美枚举类型实例向上转型后,不可再用values(),解决办法如下:

for(Size size :Size.class.getEnumConstants()) {
			System.out.println("size : " + size);
		}

        调用类字面常量的getEnumConstants()可以解决这个问题,非类字面常量调用则返回null

1.3枚举类型的进一步扩充

    枚举类型本身是不可继承的,除此之外,他与一般的类并没有太大的区别

enum Size{
		SMALL(1),MIDDLE(2),BIG;//枚举类型的具体实例,调用构造方法
		
		int i;//可以拥有变量
		
		Size(){//可以有构造方法
			this.i = 0;
		}
		Size(int i){//方法可以重载
			this.i = i;
		}
		
		public void info() {//普通方法
			System.out.println(i);
		}
		
		public static void main(String[] args) {//甚至可以有main方法
			
		}
		
	}

还可以实现类似多态的行为

enum Size{
		//枚举类型的具体实例,可以调用构造方法,也可以重写抽象方法和一般方法(可选)
		SMALL(1){
			void print() {
				System.out.println(this.name() + i);
			}
			public void getI() {
				System.out.println("重写后的i=" + i);
			}
		},
		MIDDLE(2){
			void print() {
				System.out.print("xxxxxxxxx");
			}
		},
		BIG{
			void print() {
				i = i + 1;
			}
		};
		
		int i;//可以拥有变量
		
		Size(){//可以有构造方法
			this.i = 0;
		}
		Size(int i){//方法可以重载
			this.i = i;
		}
		
		public void info() {//普通方法
			System.out.println(i);
		}
		
		public static void main(String[] args) {//甚至可以有main方法
			
		}
		
		abstract void print();//具体的枚举实例会进行重写,不同的实例调用方法会有不同的行为
		
		public void getI() {//一般的方法可以选择性的重写
			System.out.println("i = " + i);
		}
		
	}	


二.枚举类型的分类管理

    2.1利用接口组织枚举类型

public interface Food {
  enum Appetizer implements Food {
    SALAD, SOUP, SPRING_ROLLS;
  }
  enum MainCourse implements Food {
    LASAGNE, BURRITO, PAD_THAI,
    LENTILS, HUMMOUS, VINDALOO;
  }
  enum Dessert implements Food {
    TIRAMISU, GELATO, BLACK_FOREST_CAKE,
    FRUIT, CREME_CARAMEL;
  }
  enum Coffee implements Food {
    BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
    LATTE, CAPPUCCINO, TEA, HERB_TEA;
  }
}

        这样便可以将所有的枚举类型的实例向上转型为同一类型

2.2利用接口+枚举实现枚举的枚举

public enum Course {
  APPETIZER(Food.Appetizer.class),
  MAINCOURSE(Food.MainCourse.class),
  DESSERT(Food.Dessert.class),
  COFFEE(Food.Coffee.class);
  private Food[] values;
  private Course(Class<? extends Food> kind) {
    values = kind.getEnumConstants();
  }
}
2.3重新组织以上两段代码,得到更好的组织方式,更好理解代码
public enum Meal2 {
  APPETIZER(Food.Appetizer.class),
  MAINCOURSE(Food.MainCourse.class),
  DESSERT(Food.Dessert.class),
  COFFEE(Food.Coffee.class);
  private Food[] values;
  private Meal2(Class<? extends Food> kind) {
    values = kind.getEnumConstants();
  }
  public interface Food {
    enum Appetizer implements Food {
      SALAD, SOUP, SPRING_ROLLS;
    }
    enum MainCourse implements Food {
      LASAGNE, BURRITO, PAD_THAI,
      LENTILS, HUMMOUS, VINDALOO;
    }
    enum Dessert implements Food {
      TIRAMISU, GELATO, BLACK_FOREST_CAKE,
      FRUIT, CREME_CARAMEL;
    }
    enum Coffee implements Food {
      BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
      LATTE, CAPPUCCINO, TEA, HERB_TEA;
    }
  }
} 

三.枚举类型的应用

 3.1单例模式

          我的另一篇关于单例模式的文章------点击打开链接

 3.2职责链模式

 3.3状态机

 3.4多路分发

    Java本身只支持单路分发,即当下要执行的操作含有两个类型未知的对象是,Java虚拟机只能判定其中一个对象的具体类型,

而双路分发则可以实现两个位置类型的对象自己交流,而不用我们自己去判断其中一个对象的类型。多路分发依此类推。

enum Outcome{WIN,LOSE,DRAW}//模拟石头剪刀布的结果
public enum RoShamBo implements someInterface{//将具体实例向上转型为实现的接口
  PAPER(DRAW, LOSE, WIN),//预先得到比赛的结果,然后放在本地变量中,顺序有要求
  SCISSORS(WIN, DRAW, LOSE),
  ROCK(LOSE, WIN, DRAW);
  private Outcome vPAPER, vSCISSORS, vROCK;
  RoShamBo(Outcome paper,Outcome scissors,Outcome rock) {
    this.vPAPER = paper;
    this.vSCISSORS = scissors;
    this.vROCK = rock;
  }	
  public Outcome compete(RoShamBo it) {//调用compete方法实现第一次分发
    switch(it) {//switch实现第二次分发
      default:
      case PAPER: return vPAPER;
      case SCISSORS: return vSCISSORS;
      case ROCK: return vROCK;
    }
  }
} 


四.枚举类型的小知识点

4.1静态导入

     枚举类型的使用可以不写类名

import static package.Enum.*//package是包名,Enum是枚举类型

4.2和switch配合使用也可以不写枚举名

4.3有两个相关的数据结构,EnumSet,EnumMap



        

        



猜你喜欢

转载自blog.csdn.net/zh328271057/article/details/80496218