欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaSe基础(1)-----枚举类型

程序员文章站 2024-03-23 12:37:16
...

 

思维导图

JavaSe基础(1)-----枚举类型

一.枚举类型的基础知识

 

1.1枚举类型的简单实现

enum Size{SMALL,MIDDLE,BIG}

1.2枚举类型的常用方法

    1.2.1一般方法

        JavaSe基础(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