JavaSE(三十五)-枚举ENUM
  eZw8kcl3fQWu 2023年11月05日 85 0



文章目录

  • 1.枚举概述
  • 1.1.什么是枚举类型
  • 1.2.枚举历史
  • 2.定义枚举类型
  • 3.枚举与switch
  • 4.枚举与类
  • 4.1. 所有枚举类都是Enum的子类
  • 4.2. 枚举类的构造器
  • 4.3. 枚举类的方法
  • 4.4. 枚举类的属性
  • 4.5 使用匿名类来创建枚举常量
  • 5.使用匿名类来创建枚举常量
  • 5.1.枚举也是编译期状态


1.枚举概述

1.1.什么是枚举类型

word文档的对齐方式有几种:左对齐、居中对齐、右对齐;

开车的方向有几种:前、后、左、右;

枚举就是有限实现个数的类型,你可能会说,byte类型也只有256个,没错,但我们真实定义为枚举的类型,一般最多也就十多个实例,再多就不会定义为枚举了。

1.2.枚举历史

枚举是JDK1.5版本新增的特性(泛型、For-each等如今被广泛应用的特性也是由JDK1.5时所新增的),另外到了JDK1.6后switch语句支持枚举类型。

在JDK1.4之前没有枚举类型,都是使用int或字符串类型来表示枚举,如果枚举只有两个选项,那么连int都用不上,只需要使用boolean类型即可。

JDK1.5又新增了枚举类型。

2.定义枚举类型

定义枚举类型需要使用enum关键字,例如:

/**
 * @Description l枚举
 */
public enum Direction {
	
	FRONT, BEHIND, LEFT, RIGHT;
}

说明:

注意,每个枚举选项之间是用逗号隔开的。如果枚举类没有构造器、方法等,在最后一个枚举选择后面可以不打分号。但是如果枚举类还有其他成员,那么就要在最后一个枚举项后面添加分号了。

Direction类型只有四个选项,你可以理解为这个枚举类只有四个实例对象一样。外界无法去创建新的枚举对象,只能从这四个中去选择。

其实大多数时候,我们使用枚举类型还是与以及使用int或String表示的枚举一样,基本上都是很简单的。

  • 1,定义枚举类——关键字 enum (地位与class、interface相同)。
  • 2,枚举类是一个特殊的类,可以有成员变量、方法,实现一个或多个接口,定义自己的构造器。
  • 3,一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须和该枚举类的类名相同。

3.枚举与switch

1.5开始枚举类型可以在switch中使用!在1.7之后,String类型也可以放到switch中使用了。

public class Test {

	public static void main(String[] args) {

		Direction d = Direction.FRONT;
		switch (d) {
		case FRONT:
			System.out.println("前面");
			break;
		case BEHIND:
			System.out.println("后面");
			break;
		case LEFT:
			System.out.println("左面");
			break;
		case RIGHT:
			System.out.println("右面");
			break;
		default:
			System.out.println("错误的方向");
		}
		Direction d1 = d;
		System.out.println(d1);
	}
}

注意,在switch中,不能使用枚举类名称,例如:“case Direction.FRONT:”这是错误的,因为编译器会根据switch中d的类型来判定每个枚举类型,在case中必须直接给出与d相同类型的枚举选项,而不能再有类型。

4.枚举与类

4.1. 所有枚举类都是Enum的子类

JavaSE(三十五)-枚举ENUM_Java


所有枚举类都默认是Enum类的子类,无需我们使用extends来继承。这说明Enum中的方法所有枚举类都可以的。

  • int compareTo(E e):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序,例如FRONT的下标为0,BEHIND下标为1,那么FRONT小于BEHIND;
  • boolean equals(Object o):比较两个枚举常量是否相等;
  • int hashCode():返回枚举常量的hashCode;
  • String name():返回枚举常量的名字;
  • int ordinal():返回枚举常量在枚举类中声明的序号,第一个枚举常量序号为0;
  • String toString():把枚举常量转换成字符串;
  • static T valueOf(Class enumType, String name):把字符串转换成枚举常量。

JavaSE(三十五)-枚举ENUM_JavaSE_02

4.2. 枚举类的构造器

枚举类也可以有构造器,构造器不能给出访问修饰,而且默认都是private构造器。因为枚举类的实例不能让外界来创建!

/**
 * @author bruceliu
 * @Description l枚举
 */
public enum Direction {
	
	//在枚举常量后面必须添加分号,因为在枚举常量后面还有其他成员时,分号是必须的。枚举常量必须在枚举类中所有成员的上方声明。
	FRONT, BEHIND, LEFT, RIGHT;
	
	//枚举类的构造器不可以添加访问修饰符,枚举类的构造器默认是private的。但你自己不能添加private来修饰构造器。
	Direction(){
		System.out.println("hello");
	}
}

4.3. 枚举类的方法

再次强调,枚举类也是类,也可以有构造器、方法和属性,只是对构造器有一些限制而已。在语法上有一些怪异罢了!

/**
 * @Description l枚举
 */
public enum Direction {

	// 在枚举常量后面必须添加分号,因为在枚举常量后面还有其他成员时,分号是必须的。枚举常量必须在枚举类中所有成员的上方声明。
	FRONT, BEHIND, LEFT, RIGHT;

	// 枚举类的构造器不可以添加访问修饰符,枚举类的构造器默认是private的。但你自己不能添加private来修饰构造器。
	Direction() {
		System.out.println("hello");
	}

	//给枚举类添加方法
	public void fun() {
		System.out.println("hello Enum!");
	}
}

4.4. 枚举类的属性

枚举类也可以有属性。但是,如果每个枚举常量的属性值如果都相同,那就失去了意义,我们需要让每个枚举常量的属性值不同,那么就需要自己使用构造器来创建枚举常量,然后在构造器中给每个枚举常量传递不同的值。

public enum Direction {

	FRONT("前面"), BEHIND("后面"), LEFT("左面"), RIGHT("右面");

	Direction() {
		System.out.println("hello");
	}

	// 给本类添加一个实例属性prop
	//为本类设置一个有参构造器,本类只有这一个构造器,那么说明在声明枚举常量时必须调用本构造器。每个常量都会传递一个字符串给自己的explain属性。
	private String prop;

	Direction(String prop) {
		this.prop = prop;
	}

	public String getProp() {
		return prop;
	}

	public void setProp(String prop) {
		this.prop = prop;
	}

	// 给枚举类添加方法
	public void fun() {
		System.out.println("hello Enum!");
	}
}

使用

public class Test {

	public static void main(String[] args) {
		
		System.out.println(Direction.BEHIND.getProp());
	}
}

4.5 使用匿名类来创建枚举常量

还可以使用匿名类来创建枚举常量,这说明枚举常量的类型是当前枚举类的子类,而且是个匿名类。但是我们知道就算给匿名类添加了自己独有的方法,也是无法调用的,因为匿名类没有名字,只能使用父类的引用指向匿名类的实例,而多态之后只能调用父类中存在的方法。所以,使用这种情况时,通常是为了让每个枚举常量重写当前枚举类中的方法(抽象方法)。

匿名类的方法来重写父类的方法。这时每个枚举常量的真实类型都是Direction的子类类型了!而且重写了fun()方法。

/**
 * @Description 
 */
public enum Direction {

	FRONT() {
		public void fun() {
			System.out.println("FROND:重写了fun()方法");
		}
	}, 
	
	BEHIND() {
		public void fun() {
			System.out.println("BEHIND:重写了fun()方法");
		}
	}, 
	
	LEFT() {
		public void fun() {
			System.out.println("LEFT:重写了fun()方法");
		}
	},
	
	RIGHT() {
		public void fun() {
			System.out.println("RIGHT:重写了fun()方法");
		}
	};
	
	public void fun() {
		System.out.println("没有意义的方法");
	}
}
  • 使用:
//调用枚举常量的方法!
Direction.FRONT.fun();
Direction.BEHIND.fun();
Direction.LEFT.fun();
Direction.RIGHT.fun();

通常fun()方法应该定义为抽象的方法,因为每个枚举常量都会去重写它。
你无法把Direction声明为抽象类,但需要声明fun()方法为抽象方法。

/**
 * @Description 
 */
public enum Direction {

	FRONT() {
		public void fun() {
			System.out.println("FROND:重写了fun()方法");
		}
	}, 
	
	BEHIND() {
		public void fun() {
			System.out.println("BEHIND:重写了fun()方法");
		}
	}, 
	
	LEFT() {
		public void fun() {
			System.out.println("LEFT:重写了fun()方法");
		}
	},
	
	RIGHT() {
		public void fun() {
			System.out.println("RIGHT:重写了fun()方法");
		}
	};
	
	//如果在Direction类中没有fun()方法,这个类也不会有编译的问题,但是每个常量都是匿名类类型,我们是无法调用匿名类独有的方法的。
	//只需要把fun()方法修改为抽象方法,但不可以把Direction类声明为抽象类
	public abstract void fun();
}

5.使用匿名类来创建枚举常量

5.1.枚举也是编译期状态

其实枚举也是编译期状态,在运行时JVM并不知道什么是枚举类型。这也就是说,编译器需要把枚举类型转换成普通类。

public enum Direction {

	FRONT, BEHIND, LEFT, RIGHT;
}

JavaSE(三十五)-枚举ENUM_开发语言_03

JavaSE(三十五)-枚举ENUM_开发语言_04


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
eZw8kcl3fQWu