枚举

本文深入解析Java枚举的定义及使用方法,涵盖自定义枚举类、枚举类的抽象方法、实现接口等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0.枚举知识体系


Java中全部枚举知识可以用下图来表示。


1.枚举类定义


枚举类:类的对象个数有限且内容固定,如季节,只能有4个对象;性别,只能2个。


2.自定义枚举类(JDK1.5之前)


(1)字段使用private final修饰,原因对象固定,确定后就不再改变。
(2)private 修饰构造器,对象固定,不能在外创建对象,所以构造器私有化。

(3)该类的所有实例都用public static final修饰,因为是个数是固定的,所以类的内部创建对象,外部访问到对象代表公有,不能修改,对象名定义加入命名空间,如SEASON_SUMMER。


如下代码定义一个方向枚举类:

class Direction {
	//3.<span style="font-family: SimSun;">所有实例都用public static final修饰,</span>Direction类的所有对象,以内部类形式体现。
	public static final Direction DIRECTION_EAST = new Direction("东","东东东");
	public static final Direction DIRECTION_WEST = new Direction("西","西西西");
	public static final Direction DIRECTION_SOUTH = new Direction("南","南南南");
	public static final Direction DIRECTION_NORTH = new Direction("北","北北北");

	//1.<span style="font-family: SimSun;">字段使用private final修饰</span>
	private final String name;
	private final String desc;
	//方法
	public String getName(){
		return this.name;
	}
	public String getDesc(){
		return this.desc;
	}
	//重写toString方法
	public String toString(){
		return "Direction[Name:"+this.name+";Desc:"+this.desc+"]";
	}
	//2.私有化构造器
	private Direction(String name,String desc){
		this.name = name;
		this.desc = desc;
	}

}


3.enum定义枚举类(JDK1.5后)


0)enum级别


enum与interface、class级别是一样,可看成特殊的class;与class一样,一个java源文件最多只能定义一个public访问权限的枚举类,且该源文件也必须和枚举类类名相同。


1)定义说明


(1)枚举类的所有实例必须在枚举类的第一行列出(, 分隔 ;结尾),否则枚举类不能产生实例。
(2)private final修饰枚举类的属性,并且在构造器中赋值。
(3)构造器:构造器只能使用private修饰;若枚举类显式定义了带参数构造器,则在列出枚举值时也必须传入相应参数。

如下enum关键字定义DirectionV2

enum DirectionV2{//编译生成DirectionV2.class,说明是一个类。
	//首行列出4个枚举实例,以逗号分隔,分号结尾。
	EAST,WEST,SOUTH,NORTH;
}

2)枚举类与普通类区别


(1)使用enum定义的枚举类默认继承java.lang.Enum,而不是Object,当然Enum也是继承自Object。Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。

(2)枚举类的构造器只能使用private访问控制符。

(3)枚举类的所有实例必须在枚举类第一行中显示列出,列出的实例系统会自动添加public static final修饰。

(4)所有的枚举类都提供values方法,该方法可以遍历所有的枚举值。

(5)使用enum定义、非抽象的枚举类默认使用final修饰,枚举类不能派生子类。


3)Enum类


(1)int compareTo(E o):用于与指定枚举对象比较顺序,同一枚举实例只能与相同类型枚举实例进行比较。如果该枚举对象位于指定枚举对象之后,返回正整数;如果之前,返回负整数;否则返回零。

(2)String name():返回此枚举实例的名称,定义枚举类时列出的所有枚举值之一。

(3)int ordinal():返回枚举值在枚举类中的索引值,即在枚举类中的声明位置,第一个枚举值的索引值为零。

(4)String toString():返回枚举常量的名称,与name方法相似

(5)public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name):静态方法,返回指定枚举类中指定名称的枚举值。名称必须与该枚举类中声明枚举值时所用的标识符完全匹配,不允许使用额外空白字符。

(6)values():


4)其它信息


(1)JDK1.5以后switch-case中可使用枚举类对象作为表达式。case子句可以直接使用枚举值的名字,无需添加枚举类作为限定。

(2)若枚举只有一个成员,则可以作为一种单例模式的实现方法。


5)枚举类的成员


(1)字段
枚举类的字段是确定的,所以所有的字段应该使用private final修饰,此时就必须使用构造器对其进行赋值(当然也可以在初始化块赋值或在定义时设定默认值,但是不常用),这时就需要带参数的构造器。
(2)方法
对枚举类的字段都要通过Getter来获取,并且不能有Setter。
(3)构造器

构造器必须是私有的,一旦定义了带参构造器就要在列出枚举值时传入参数。枚举类中列出枚举值时,实际上就是调用构造器创建枚举类对象,只是没有使用new关键字,也没显式调用构造器。

enum DirectionV2{
	EAST("东"),
	WEST("西"),
	SOUTH("南"),
	NORTH("北");
	private final String chName;
	public String getChName(){
		return this.chName;
	}
	private DirectionV2(String chName){
		this.chName = chName;
	}
}
public class DirectionTest{
	public static void main(String[] args){
		DirectionV2[] ds = DirectionV2.values();
		for(DirectionV2 d:ds){
			System.out.println(d.getChName());
		}
	}
}

4.枚举类的抽象方法


1)抽象方法使用实例


假设有Operation枚举类,其有2个枚举值PLUS(加)和MINUS(减),并可以进行相应运算。此时可以采用以下方法:

enum Ope{
	//首行列出,逗号分隔,分号结束。
	PLUS{
		public double compute(double numA,double numB){
			return numA + numB;
		}
	},
	MINUS{
		public double compute(double numA,double numB){
			return numA - numB;
		}
	};
	//枚举类中的抽象方法
	public abstract double compute(double numA,double numB);
}
public class OpeTest{
	public static void main(String[] args) 
	{
		System.out.println(Ope.MINUS.compute(23,1.5));
	}
}

2)要点说明


(1)上述程序编译会产生4个.class文件,OpeTest.class,Ope.class,Ope$1.class,Ope$2.class。

(2)枚举类定义抽象方法时不需要abstract把枚举类定义成抽象类,系统会自动添加abstract关键字;

(3)枚举类中显式创建了枚举值,其实是枚举类的内部类并且继承了外部的枚举类,所以在定义每个枚举值时必须为抽象方法提供实现,否则会出现如下编译错误:

OpeTest.java:4: error: Ope is abstract; cannot be instantiated


5.实现接口的枚举类


1)枚举类实现

枚举类也可以实现一个或多个接口,也需要实现接口中的所有方法。

interface DirectionV2Desc
{
	public void desc();
}
enum DirectionV2 implements DirectionV2Desc//编译生成DirectionV2.class,说明是一个类。
{
	//首行列出4个枚举实例,以逗号分隔,分号结尾。
	EAST,WEST,SOUTH,NORTH;
	public void desc(){
		System.out.println("方向的枚举类");
	}
}
public class DirectionTest
{
	public static void main(String[] args){
		DirectionV2[] ds = DirectionV2.values();
		for(DirectionV2 d:ds){
			d.desc();//调用desc()方法
		}
	}
}

  

2)枚举值实现


如果每个枚举值希望调用接口方法显示不同的行为方式,可让每个枚举值分别实现该方法。

interface DirectionV2Desc
{
	public void desc();
}
enum DirectionV2 implements DirectionV2Desc//编译生成DirectionV2.class,说明是一个类。
{
	//首行列出4个枚举实例,以逗号分隔,分号结尾。
	EAST{
		public void desc(){
			System.out.println("这是东方");
		}
	},
	WEST{
		public void desc(){
			System.out.println("这是西方");
		}
	},
	SOUTH{
		public void desc(){
			System.out.println("这是南方");
		}
	},
	NORTH{
		public void desc(){
			System.out.println("这是北方");
		}
	};
}
public class DirectionTest
{
	public static void main(String[] args){
		DirectionV2[] ds = DirectionV2.values();
		for(DirectionV2 d:ds){
			d.desc();//调用desc()方法
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值