J2SE_枚举类

一、什么是枚举类

在JDK1.5之前,Java有两种方式定义新类型:类和接口。对于大部分面向对象编程来说,这两种方法似乎够了。但是在一些特殊情况下,这些方法就不是和合适。例如:想定义一个Color类,它只能够有Red, Blue, Black3种值,其他任何值都是非法的,那么在虽然在JDK1.5之前可以构造这样的代码,但是要做很多的工作,就可能会带来各种不安全的问题。而JDK1.5之后引入的枚举类型(Enum)就能够避免这些问题。

枚举类本质上还是一个类,每一个枚举类都继承了抽象类Enum。

二、JDK1.5之前实现枚举功能的类

1)通过private将其构造方法私有化,使得在类的外部无法实例化该类

2)该类所有可能的实例都使用public static final 来修饰的属性保存起来

3)提供静态方法,允许通过特定的参数来获取与之匹配的实例

示例代码:

package com.wbf.enum1;

//JDK1.5之前,实现枚举功能的类
class Color {
	public static final Color RED = new Color("红色");
	public static final Color BLUE = new Color("蓝色");
	public static final Color BLACK = new Color("黑色");
	
	private String name;
	private Color(String n){
		this.name = n;
	}
	
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return this.name;
	}
	
	public static Color getInstance(Integer colorNum){
		
		switch(colorNum){
			case 1 : 
				return RED;
			case 2 : 
				return BLUE;
			case 3 : 
				return BLACK;
			default : 
				return null;
		}
	}
}

public class EnumDemo1 {
	public static void main(String[] args) {

		Color c = Color.getInstance(1);
		System.out.println(c.getName());
		c = Color.getInstance(2);
		System.out.println(c.getName());
	}
}
三、使用enum关键字来定义一个枚举类,实现如下操作

1)获取枚举的指定内容

2)遍历枚举常量

3)switch和枚举一起使用

代码实例如下:

package com.wbf.enum2;

//使用关键字enum来定义枚举类
enum Color{
	RED, BLUE, BLACK;
}

public class EnumDemo2 {

	public static void main(String[] args) {
		//枚举.variable来取出枚举指定内容
		Color color = Color.BLUE;
		System.out.println(color);
		
		//遍历枚举常量
		//枚举.values()方法将全部的枚举常量变成数组,之后使用foreach输出
		Color[] colors = Color.values();
		for (Color c : colors)
		{
			//ordinal()方法返回枚举常量序号
			//name()方法返回枚举常量名称
			System.out.println(c.ordinal() + " ---> " + c.name());
		}
		
		//枚举和switch
		switch(Color.BLUE){
			case RED : 
				System.out.println("red");
				break;
			case BLUE : 
				System.out.println("blue");
				break;
			case BLACK : 
				System.out.println("black");
				break;
			default : 
				System.out.println("doesn't exist!");
		}
	}
}
四、枚举类实现一个接口

每一个枚举类对象都实现接口的抽象方法, 其实枚举类实现接口和普通类没多少区别,也是使用implements关键字,可以实现一个或多个接口。但是需要注意的是,如果像普通类一样实现接口后直接重写接口里的方法的话,那么枚举类的所有实例就拥有一样的接口实现了,这样就失去了意义和灵活性,所以往往会为每个实例提供不同的方法实现。示例代码如下:

package com.wbf.enum3;

interface Print {
	//public abstract String getColor();
	String getColor();
}

//枚举类实现一个接口
//每一个枚举类对象都实现接口的抽象方法
enum Color implements Print {
	RED {			
		public String getColor(){
			return "红色";
		}
	}, 
	BLUE {
		public String getColor() {
			return "蓝色";
		}
	}, 
	BLACK {
		public String getColor() {
			return "黑色";
		}
	};
}

public class EnumDemo3 {

	public static void main(String[] args) {
		Color c = Color.BLACK;
		System.out.println(c.getColor());
	}
}
五、枚举类中定义抽象方法

每一个枚举对象都会实现该抽象方法,类似与实现接口中的抽象方法。

枚举类中定义了抽象方法,但是,类却没用abstract修饰,这点跟普通类不一样,因为枚举类需要显示创建枚举值,并为抽象方法提供实现,否则会出现编译错误。

示例代码如下:

package com.wbf.enum4;

//枚举类中定义抽象方法
//每一个枚举对象都会实现该抽象方法
enum Color {
	RED {			
		public String getColor(){
			return "红色";
		}
	}, 
	BLUE {
		public String getColor() {
			return "蓝色";
		}
	}, 
	BLACK {
		public String getColor() {
			return "黑色";
		}
	};
	
	public abstract String getColor();
}

public class EnumDemo4 {

	public static void main(String[] args) {
		Color c = Color.BLACK;
		System.out.println(c.getColor());
	}
}
六、通过构造方法,为每一个枚举对象属性赋值

因为在枚举类中已经明确的写出了一个带有参数的构造方法,所以定义枚举常量的时候就必须调用该构造方法。代码实例如下:

package com.wbf.enum5;

enum Color {
	//因为在枚举类中已经明确的写出了一个带有参数的构造方法,所以定义枚举常量的时候就必须调用该构造方法
	RED("红色"), BLUE("蓝色"), BLACK("黑色");
	
	private String name;
	private Color(String name){
		System.out.println("构造方法被调用...");
		this.setName(name);
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return this.name;
	}
}

//通过构造方法,为每一个枚举对象属性赋值
public class EnumDemo5 {
	public static void main(String[] args) {
		
		for (Color c : Color.values())
		{
			System.out.println(c.ordinal() + " ---> " + c.name() + "(" + c.getName() + ")");
		}
	} 
}
七、通过setter方法为每一个枚举对象的属性赋值

这样的话就必须明确的知道是哪一个枚举常量,枚举常量是RED, 则name属性应该是"红色"。代码实例如下:

package com.wbf.enum7;

enum Color {
	RED, BLUE, BLACK;
	
	private Color(){
		System.out.println("构造方法被调用...");
	}
	
	private String name;
	public void setName(String name){
		switch(this){
			case RED :{
				if ("红色".equals(name)){					
					this.name = name;
				} else {
					System.out.println("设置内容错误");
				}
				break;
			}
			case BLUE : {
				if ("蓝色".equals(name)){					
					this.name = name;
				} else {
					System.out.println("设置内容错误");
				}
				break;
			}
			case BLACK : {
				if ("黑色".equals(name)){					
					this.name = name;
				} else {
					System.out.println("设置内容错误");
				}
				break;
			}
		}
	}
	
	public String getName(){
		return this.name;
	}
}

//通过setter方法为每一个枚举对象的属性赋值,但是这样的话就必须明确的知道是哪一个枚举常量
//如:枚举常量是RED, 则name属性应该是"红色"
public class EnumDemo7 {
	public static void main(String[] args) {
		
		Color c = Color.BLACK;
		c.setName("蓝色");
		c.setName("黑色");
		System.out.println(c.getName());
	} 
}
八、类集对枚举的支持EnumMap, EnumSet

示例代码:

package com.wbf.enum6;

import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;

enum Color {
	RED, BLUE, BLACK;
}

//类集对枚举的支持EnumMap, EnumSet
public class EnumDemo6 {
	public static void main(String[] args) {
		
		//EnumMap, Map接口的子类, 要使用EnumMap必须先创建EnumMap对象, 创建此对象时必须指定要操作的枚举类型
		Map<Color, String> enumMap = new EnumMap<Color, String>(Color.class);
		enumMap.put(Color.RED, "红色");
		enumMap.put(Color.BLUE, "蓝色");
		enumMap.put(Color.BLACK, "黑色");
		
		System.out.println("---输出全部内容---");
		for (Color c : Color.values())
		{
			System.out.println(c.name() + ", " + enumMap.get(c));
		}
		
		System.out.println("---输出keys---");
		for (Color c : enumMap.keySet())
		{
			System.out.println(c.ordinal() + " ---> " + c.name());
		}
		
		System.out.println("---输出values---");
		for (String s : enumMap.values())
		{
			System.out.println(s);
		}
		
		//EnumSet是Set接口的子类,内容不可重复,不能够直接使用关键字new对其进行实例化,但是所在的类提供了很多static方法
		System.out.println("---将全部的枚举值设置到EnumSet中---");
		EnumSet<Color> enumSet1 = EnumSet.allOf(Color.class);
		print(enumSet1);
		
		System.out.println("---只设置一个枚举常量到EnumSet中---");
		EnumSet<Color> enumSet2 = EnumSet.of(Color.BLUE);
		print(enumSet2);
		
		System.out.println("---创建只能够放入指定枚举类型的EnumSet---");
		EnumSet<Color> enumSet3 = EnumSet.noneOf(Color.class);
		enumSet3.add(Color.RED);
		enumSet3.add(Color.BLUE);
		print(enumSet3);
		
		System.out.println("---创建不包含指定元素的集合---");
		EnumSet<Color> enumSet4 = EnumSet.complementOf(enumSet3);
		print(enumSet4);
		
		System.out.println("---复制已有的内容---");
		EnumSet<Color> enumSet5 = EnumSet.copyOf(enumSet3);
		print(enumSet5);
		
	} 
	
	public static void print(EnumSet<Color> temp){
		
		for (Color c : temp)
		{
			System.out.print(c.name() + "、");
		}
		System.out.println();
	}
}

九、小结

1)使用enum定义的枚举类默认继承了java.lang.Enum类,而不是直接继承Object类。java.lang.Enum类实现了java.lang.Serialiable和java.lang.Comparable两个接口,证明枚举类型可以使用比较器和序列化操作。

2)枚举类的构造器只能使用private修饰,即使省略也默认是private的。

3)枚举类实例只能显示给出,否则永远不能产生实例,列出这些实例时,系统会自动添加public static final修饰,无需程序员显示添加。

4)所有枚举类都提供了一个values方法,用于可以很方便地遍历所有枚举值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值