枚举

思维导图

java 定义枚举 报错 java定义枚举之间的关系_构造器

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;
	     }
	 }
}