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

Java学习系列(二十二)Java面向对象之枚举详解

程序员文章站 2022-05-01 10:34:38
...

 

 

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45332565

 

一、前言

 

今天我们来讲讲枚举,希望通过这篇博客大家能对枚举有个更全面的了解。枚举是一种实例(大写)数固定的类(不能再创建实例),枚举改变了常量的声明方式,而且它在编译期间就限定了类型。枚举多用于确定的状态数(如:鼠标上下左右、IM消息已读未读)、类型数(如:系统、聊天、添加好友消息,我的他的)、模式数(回复、评论模式,刷选、全部模式)等等。枚举和类一样,同样有抽象类、可以实现接口、可含内部类、初始化块,值得注意的是:枚举的构造器无论是否使用private修饰,默认总是被private修饰;当然,枚举变量也可以在switch使用。下面我们通过实例来全面了解一下Java中的枚举。

 

二、实例说明

(1)实例演示
/**
 * 修饰符 enum 枚举名{ 
 * 		//立即在第一行列出该枚举的所有实例(但实际上是创建枚举实例,会默认调用无参构造器)。 
 * }
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @since version 1.0
 * @datetime 2015年4月27日 下午8:36:44
 */

public enum Gender {
	// MALE("男")相当于:Gender MALE = new Gender("男");
	// 列出所有枚举值,也就是该枚举所有可能的实例--实例列表
	// WOMENMALE其实默认就是WOMENMALE()
	MALE("男"), FEMALE("女"), MANMALE(), WOMENMALE;
	private String name;

	// --构造器无论是否使用private修饰,默认总是被private修饰
	Gender() {
		System.out.println("无参构造方法被调用...");
	}

	private Gender(String name) {
		System.out.println("含参构造方法被调用..." + name);
		this.name = name;
	}

	// 注意:初始化块只能被static修饰。
	// 编译时实例初始化块的代码都会被提取到构造器的“最前面”,所以它执行的优先级高于构造器
	{
		System.out.println("实例初始化块....");
	}

	// 当类被加载后,对类初始化后时被隐式执行,且一个JVM对一个类只初始化一次。
	static {
		System.out.println("静态/类初始化块...");
	}

	public void info() {
		System.out.println(this + " 枚举中的info方法被调用");
	}

	/**
	 * 枚举在switch中的使用 --switch(byte/short/char/int/String/枚举)
	 * 
	 * @param gender
	 */
	public static void chooseSex(Gender gender) {
		if (gender == null) {
			return;
		}
		switch (gender) {// 传一个枚举变量给switch
		case MALE:
			System.out.println("男性...");
			break;
		case FEMALE:
			System.out.println("女性...");
			break;
		case MANMALE:
			System.out.println("男同...");
			break;
		case WOMENMALE:
			System.out.println("女同...");
			break;
		default:
			break;
		}
	}

	class A {
		{
			System.out.println("A中实例初始化块...");
		}

		public void info() {
			System.out.println(this + "A类中的info方法被调用");
		}
	}

	public static void main(String[] args) {
		// 初始化块及构造器(无参或含参)按实例列表顺序挨个被执行,接着执行静态(类)初始化块
		Gender g1 = Gender.MALE;
		Gender.chooseSex(g1);
		g1.info();

		// 创建寄生类(内部类)实例
		A a = g1.new A();
		a.info();

		// 打印该枚举变量g1所在的实例列表所在的位置,从0开始
		System.out.println(g1.ordinal());
		// Gender g2 = Gender.FEMALE;
		// System.out.println(g2.ordinal());

		// 打印该枚举的所有实例
		for (Gender g : Gender.values()) {
			System.out.println(g);
		}
	}
}


========= 打印结果 =============
实例初始化块....
含参构造方法被调用...男
实例初始化块....
含参构造方法被调用...女
实例初始化块....
无参构造方法被调用...
实例初始化块....
无参构造方法被调用...
静态/类初始化块...
男性...
MALE 枚举中的info方法被调用
A中实例初始化块...
com.leo.enumation.Gender$A@c17164A类中的info方法被调用
0
MALE
FEMALE
MANMALE
WOMENMALE
 

(2)下面看看抽象枚举的使用
// 编译器将把注解信息记录在class文件中,当运行Java程序时JVM会保留注解,因此可以通过反射机制来读取注解的信息。
@Retention(RetentionPolicy.RUNTIME)
// 注解作用在类上面
@Target(ElementType.TYPE)
public @interface ClassName {
	// 声明默认值
	String name() default "计算";

	// 特殊的值
	String value();
}
/**
 * 利用抽象枚举来模拟一个四则运算,需要创建匿名内部类来重写相关抽象方法。
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @since version 1.0
 * @datetime 2015年4月27日 下午10:14:02
 */

// 指定用的是哪个自定义注解的类,若把name去掉,则name默认为:计算
@ClassName(name = "枚举", value = "四则运算")
public enum Calculator {

	ADD("张三") {
		@Override
		public double eval(double x, double y) {
			return x + y;
		}
	},

	SUB {
		@Override
		public double eval(double x, double y) {
			return x - y;
		}
	},

	MULTIPLY {
		@Override
		public double eval(double x, double y) {
			return x * y;
		}
	},

	DIVIDE {
		@Override
		public double eval(double x, double y) {
			if (y == 0) {
				throw new ArithmeticException("除数不能为0");
			}
			return x / y;
		}
	};
	private String name;

	private Calculator() {
		System.out.println("无参构造器被执行..." + this);
	}

	private Calculator(String name) {
		this.name = name;
		System.out.println("含参构造器被执行..." + this.name);
	}

	public abstract double eval(double x, double y);

	public static void main(String[] args) throws ClassNotFoundException {
		Calculator c1 = Calculator.ADD;
		System.out.println(c1.eval(1, 2));

		// Calculator c2 = Calculator.SUB;
		// System.out.println(c2.eval(1, 2));

		// 打印该枚举的一些注解信息
		Class<?> clazz = Class.forName("com.leo.enumation.Calculator");
		ClassName cn = clazz.getAnnotation(ClassName.class);
		System.out.println(cn.name() + " ," + cn.value());
	}
}

(3)枚举实现接口
interface IDirection {
	void pointDirection();
}

/**
 * 枚举实现接口
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @since version 1.0
 * @datetime 2015年4月27日 下午11:01:50
 */

public enum Orientation implements IDirection {
	EAST, WEST, SOUTH(), NORTH;

	@Override
	public void pointDirection() {
		System.out.println("指向 ---> " + this);
	}

	public static void main(String[] args) {
		IDirection direction = Orientation.SOUTH;
		direction.pointDirection();
	}
}

三、总结

 

关于Java中的枚举相关知识点大体就这些了,后面讲陆续更新内部类、正则表示式、改善Java代码质量的一些建议等等,敬请关注!