枚举类
概念:
枚举类型:可以把有固定格式的一些数据定义为枚举类型,它的数量是有限并且固定的。比如一周有7天,一年有4个季节一样,一个小时有60分钟等,都是有限的并且固定的数据。比如一周有七天,分别是Sunday、Monday、Tuesday、Wednesday、Thursday、Friday和Saturday。如果我们可以用整数0、1、2、3、4、5、6来表示这七天,那么多下来的那些整数该怎么办?而且这样的设置很容易让数据出错,即取值超出范围。我们能否自创一个数据类型,而数据的取值范围就是这七天呢?枚举类就是干这个的,我可以定义一个枚举类型可以用0-6来代表这7天,或者用1-7随你便,这个枚举中就只有这7个数字了。这就是枚举。
语法:
枚举类跟普通类一样也是类,只要把class换成enum就是枚举类了。
特点:
a) 定义枚举类时先要在第一行声明枚举值,权限默认强制就是public static final,多个枚举值用逗号做分隔符。枚举值其实就是这个枚举类创建的对象。比如Season枚举类中 SPRING,SUMMER 2个枚举值,其实就是 public static final Season SPRING =new Season(形参列表)。另一个SUMMER也是这个格式的对象。
b) 枚举类的构造器只能强制使用private权限,可以省略不写。
c) 枚举类本身强制使用final修饰符修饰,final类不能被继承,所以不能产生子类。
d) 枚举类不是普通类,所以它没有继承java.lang.Object类,它继承的是 java.lang.Enum类。
例子均参考自本人看书并做的笔记《某Java书籍》
例子:枚举值展开形式:
public enum SeasonEnum
{
SPRING,SUMMER,FALL,WINTER;
//上面的枚举值相当于下面的简写形式:
//public static final SeasonEnum SPRING = new SeasonEnum();
//public static final SeasonEnum SUMMER = new SeasonEnum();
//public static final SeasonEnum FALL = new SeasonEnum();
//public static final SeasonEnum WINTER = new SeasonEnum();
}
public class EnumTest
{
public void test(SeasonEnum s)
{
switch(s)
{
case SPRING:
System.out.println("spring");
break;
case SUMMER:
System.out.println("summer");
break;
}
}
public static void main(String[] args)
{
for(SeasonEnum s : SeasonEnum.values()) //枚举类.values() 可以获取对象引用变量的名字。
{
System.out.println(s);
}
new EnumTest().test(SeasonEnum.SPRING);
}
}
例子:带参数的枚举值,这里枚举类同时实现接口
public interface GenderDesc
{
void info();
}
---------------------------------------------------
public enum Gender implements GenderDesc
{
MAN("man"),WOMAN("woman");
//上面带参数的枚举值,相当于以下简写形式:
//public static final Gender MAN = new MAN(“man”); //这里已经给构造器传入参数了
//public static final Gender WOMAN = new MAN(“woman”);
private final String name;
private Gender(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void info()
{
System.out.println("abc");
}
}
--------------------------------------------
public class GenderTest
{
public static void main(String[] args)
{
Gender g = Gender.MAN; //Gender.MAN 就是 对象引用变量,它的值是一个对象。对象在new的时候如果有参数需要给传入参数。这里不用,参数在new的时候已经给出了,这里并没有new。
Gender g1 = Gender.WOMAN;
//Gender g = Enum.valueOf(Gender.class, "MAN"); //这个与上面虽然没有什么区别,但是这个一看就知道是返回枚举类型的值。
//g.name = "man";
System.out.println(g.getName());
g.info(); //每个枚举值在调用方法时的操作都相同。
g1.info(); //每个枚举值在调用方法时的操作都相同。
}
}
例子:拓展上例,让不同枚举值调用info()方法,都有不同的操作。
public interface GenderDesc
{
String info(); //这个抽象方法是String类型的,也就是实现它的方法必须有return.
}
-----------------------------------------
public enum Gender implements GenderDesc
{
MAN("man") //它是一个对象, new Gender(“man”) ,所以这个整体就是一个匿名内部类。匿名内部类重写抽象方法。
{
public String info()
{
return "man info";
}
},
WOMAN("woman") //同上,匿名内部类重写抽象方法。
{
public String info()
{
return "woman info";
}
};
private final String name;
private Gender(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
----------------------------------------------------
public class GenderTest
{
public static void main(String[] args)
{
Gender g = Gender.MAN;
Gender g1 = Gender.WOMAN;
//Gender g = Enum.valueOf(Gender.class, "MAN");
//g.name = "man";
System.out.println(g.getName());
System.out.println(g.info()); //匿名内部类的对象调用它实现接口的方法。
System.out.println(g1.info());
}
}
·包含抽象方法的枚举类
·枚举类定义时候强制使用final修饰符,因为抽象方法必须定义在抽象类中,但是枚举类就是不能有子类就有final,所以将枚举类定义成抽象类就不能显示的写abstract修饰符了,直接在枚举类中定义抽象方法就可以了,这个类就成了抽象类了,但是依然有final特性,不能有子类。然后枚举类自身用类似匿名内部类(枚举值)来实现抽象方法。
·每个匿名内部类(枚举值)都必须实现抽象方法。因为Java语法规定:抽象类中不能创建对象,又因一个枚举值是一个对象,所以枚举值不能单独存在,枚举值必须作为匿名内部类存在并且这个类实现所有的抽象方法,因为类要实现抽象方法就的实现全部抽象方法。
·枚举类中定义抽象方法,这个枚举类就会变成抽象类。定义了抽象方法后就必须用匿名内部类的方式去实现抽象方法。
例子:枚举值匿名内部类
public enum Operation
{
PLUS, MINUS, TIMES, DIVIDE;
double eval(double x, double y)
{
switch(this)
{
case PLUS: return x + y;
case MINUS: return x - y;
case TIMES: return x * y;
case DIVIDE: return x / y;
default: return 0;
}
}
public static void main(String[] args)
{
System.out.println(PLUS.eval(3, 4));
System.out.println(MINUS.eval(5, 4));
System.out.println(TIMES.eval(5, 4));
System.out.println(DIVIDE.eval(5, 4));
}
}
例子:上面的拓展
public enum Operation2
{
PLUS //匿名内部类
{
public double eval(double x , double y)
{
return x + y;
}
}, //多个匿名内部类用逗号分割
MINUS //匿名内部类
{
public double eval(double x , double y)
{
return x - y;
}
},
TIMES //匿名内部类
{
public double eval(double x , double y)
{
return x * y;
}
};
//下面报错,因为枚举值是一个对象,抽象类中不能new对象。
//DIVIDE
//枚举类中定义抽象方法,这个枚举类就会变成抽象类。定义了抽象方法后就必须用匿名内部类的方法去实现抽象方法。
public abstract double eval(double x, double y);
public static void main(String[] args)
{
System.out.println(Operation2.PLUS.eval(3, 4));
System.out.println(Operation2.MINUS.eval(5, 4));
System.out.println(Operation2.TIMES.eval(5, 4));
// System.out.println(Operation2.DIVIDE.eval(5, 4));
}
}