枚举
思维导图
1、概念
1.1 定义
枚举是JDK1.5引入的新特性,通过关键字enum定义枚举类。枚举类是一种特殊的类,它的取值是有限的,如一年中的四季,一年中的十二个月,都可以被定义为枚举类,枚举可以使用构造器,定义成员变量和实现接口。
1.2 本质
java.lang.Enum的子类(所以不能继承其他类。)
1.3 声明形式
public enum Gender{ //Gender是这个枚举的名
Female,Male; //枚举中的常量(对象)
//private static final Gender Female;
//private static final Gender Male;
}
(1)枚举中的成员常量(如BLACK,WHITE)是枚举对象,只不过他们是静态常量,被static final修饰
(2)枚举对象之间用逗号隔开,最后一个对象用分号表示结尾
1.4 优点
将常量组织起来,统一管理。
2、常用方法
方法名称 | 描述 |
values() | 以数组形式返回枚举类型的所有成员 |
valueOf(String str) | 通过字符串返回枚举对象 |
compareTo | 比较两个枚举成员在定义时的顺序 |
int ordinal() | 获取枚举成员的索引位置 |
String name() | 返回枚举类型的名字 |
equlal() | 判断是不是同一个对象 |
3、获取枚举对象的方式
方式1(最常用):
public static void main(String[] args){
//使用类名直接访问类中定义的俩对象
//最常用的一种方式
Gender g = Gender.MALE;
g = Gender.FEMALE;
//可以调用从父类型Enum以及Object中继承过来的方法
System.out.println(g.name());
System.out.println(g.ordinal());
System.out.println(g.toString()); //toString
}
//运行结果:
MALE
0
MALE
方式2:
public static void main(String[] args){
//通过字符串参数的改变,可以获取到Gender中的指定的一个对象
String name = "MALE";
Gender g = Gender.valueOf(name);
System.out.println(g.name());
System.out.println(g.ordinal());
System.out.println(g.toString());
}
//运行结果:
MALE
0
MALE
方式三:
public static void main(String[] args){
//通过字符串确定是哪一个枚举类型
Class c = Class.forName("com.briup.demo.Genger");
//通过字符串确定是哪一个名字的枚举对象
String name = "FEMALE";
//可以通过改变字符串,获取到java中任何一个枚举类型中的任意一个枚举对象
Enum g = Enum.valueOf(c,name);
System.out.println(g.name());
System.out.println(g.ordinal());
System.out.println(g.toString());
}
//运行结果:
FEMALE
1
FEMALE
4、在枚举中定义属性和方法
public enum Gender{
MALE,FEMALE;
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void test(){
System.out.println("Gender test...");
}
public static void print(String name){
System.out.println("hello "+name);
}
}
public class Test{
public static void main(String[] args){
Gender g = Gender.MALE;
g.test();
g.setName("我是男生");
System.out.println(g.getName());
Gender.print("jack");
}
}
5、枚举中构造器调用
定义构造器
枚举中的构造器只能使用private修饰,或者不写任何修饰符,默认也是private,同时支持构造器重载
public enum Gender{
MALE,FEMALE;
private String name;
//无参构造
private Gender(){}
//含参构造
private Gender(String name){
this.name = name;
}
}
调用无参构造器
定义一个枚举类
public enum Gender{
MALE,FEMALE;
}
public enum Gender{
MALE(),FEMALE();
//构造器,默认private修饰
Gender(){
System.out.println("无参构造器被调用");
}
public static void main(String[] args) throws Exception{
Class.forName("全限定名"); //对Gender.class进行加载
}
}
运行结果:
无参构造器被调用
无参构造器被调用
在Gender.class完成类加载的时候,会自动调用无参构造器创建对象MALE和FEMALE,原因是因为MALE和FEMALE在枚举类型中时两个静态常量。
含参构造器
public enum Gender{
MALE("男"),FEMALE("女");
private String name;
Gender(){
System.out.println("无参构造器被调用");
}
Gender(String name){
this.name = name;
System.out.println("有参构造器被调用");
}
}
public static void main(String[] args)throws Exception {
//该代码可以对Gender.class进行类加载
Class.forName("全限定名");
}
//运行结果:
有参构造器被调用
有参构造器被调用
可以看出,枚举对象中传入了对应的参数,所以调用含参构造方法,并且也是同无参一样调用两次
7、常见使用方式
方式一:普通方式
枚举类
public enum Gender {
//枚举对象
FEMALE,MALE;
//枚举中的普通变量
private String name;
//get()和set()方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//定义了两个普通方法
public void test() {
System.out.println("Gender test...");
}
public static void print(String name) {
System.out.println("hello! " + name);
}
}
测试类
public class Demo {
public static void main(String[] args) {
//创建枚举对象
Gender g = Gender.MALE;
//调用枚举中的普通方法
g.test();
//调用setName方法为变量赋值
g.setName("rose");
System.out.println(g.getName());
//调用print方法
Gender.print("jack");
}
}
运行结果
Gender test…
rose
hello! jack
方式二:搭配switch使用
public enum Weeks {
MONDAY,TUESDAY,WEDNSDAY,
THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
//switch语句实现枚举类
class Demo{
public static void main(String[] args) {
Weeks weeks = Weeks.FRIDAY; //创建枚举对象
switch(weeks) {
case MONDAY:
System.out.println("星期一");
break;
case TUESDAY:
System.out.println("星期二");
break;
case WEDNSDAY:
System.out.println("星期三");
break;
case THURSDAY:
System.out.println("星期四");
break;
case FRIDAY:
System.out.println("星期五");
break;
case SATURDAY:
System.out.println("星期六");
break;
case SUNDAY:
System.out.println("星期日");
break;
default:
System.out.println("不在范围内");
}
}
}
方式三:枚举实现接口
有如下
//接口
interface Action{
void run();
}
//枚举Gender实现接口
public enum Gender implements Action{
MALE,FEMALE;
}
此时会编译报错,可以使用如下两个方式实现接口
方式1:在枚举中统一实现这个接口中的抽象方法
//接口
interface Action{
void run();
}
//枚举Gender实现接口
public enum Gender implements Action{
MALE,FEMALE;
@Override
public void run() {
System.out.println("枚举中统一实现接口中的抽象方法");
}
}
方式2:在每个枚举对象中分别实现这个接口中的抽象方法
//接口
interface Action{
void run();
}
//枚举Gender实现接口
public enum Gender implements Action{
MALE(){
public void run(){
System.out.println("男生对象中,单独实现接口中的抽象方法");
}
},FEMALE(){
public void run(){
System.out.println("男生对象中,单独实现接口中的抽象方法");
};
}
}
@案例:输入1或者2获取枚举中对应的颜色
import java.util.Scanner;
//定义接口
interface Action{
String paint(int index);
}
//枚举类实现接口Ation
public enum Color implements Action{
YELLOW("黄色",1),RED("红色",2);
private String color;
private int index;
private Color(){}
//构造方法
private Color(String color, int index) {
this.color = color;
this.index = index;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String paint(int index) {
// TODO Auto-generated method stub
for(Color c : Color.values()) {
if(index == c.getIndex()) {
return c.getColor();
}
}
return null;
}
}
class Demo{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int input = sc.nextInt();
Color c = Color.RED;
System.out.println(c.paint(input));
}
}
方式四:枚举中定义抽象方法
enum Color{
//枚举对象重写抽象方法
RED {
@Override
public String getColor() {
// TODO Auto-generated method stub
return "红色";
}
},GREEN {
@Override
public String getColor() {
// TODO Auto-generated method stub
return "绿色";
}
};
//抽象方法
public abstract String getColor();
}
public class Demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
for(Color c : Color.values()) {
System.out.println(c.getColor());
}
}
}
方式五:遍历枚举
public enum Color {
GREEN,YELLOW,RED; //变量?对象?感觉都是
}
//遍历
class Test{
public static void main(String[] args) {
Color[] values = Color.values(); //values()方法获取枚举中所有的对象/属性
for(Color color : values) {
System.out.println(color);
}
//简写
for(Color color : Color.values()) {
System.out.println(color);
}
}
}
方式:覆盖枚举
待补。。。
方式:接口组织枚举
定义一个接口:IEnum
public interface IEnum {
int getCode();
String getDescription();
}
//新定义一个接口Plant来组织枚举Vegetable和Fruit,在枚举中重写接口IEnum中的方法
public interface Plant {
enum Vegetable implements IEnum {
POTATO(0, "土豆"),
TOMATO(0, "西红柿");
Vegetable(int number, String description) {
this.code = number;
this.description = description;
}
private int code;
private String description;
@Override
public int getCode() {
return 0;
}
@Override
public String getDescription() {
return null;
}
}
enum Fruit implements IEnum {
APPLE(0, "苹果"),
ORANGE(0, "桔子"),
BANANA(0, "香蕉");
Fruit(int number, String description) {
this.code = number;
this.description = description;
}
private int code;
private String description;
@Override
public int getCode() {
return 0;
}
@Override
public String getDescription() {
return null;
}
}
}