1. 枚举的引出
在多例模式的使用中,我们知道构造方法私有化,类内部需要提供若干个实例化对象,后面通过static返回。
举例:定义一个描述颜色的多例类。
public class Color {
private final static int RED_NUM = 1;
private final static int BULE_NUM = 2;
private final static int BLACK_NUM = 3;
private final static Color RED = new Color();
private final static Color BLUE = new Color();
private final static Color BLACK = new Color();
//构造方法私有,只允许本类访问
private Color(){
}
public static Color getInstance(int ch){
switch(ch){
case RED_NUM:
return RED;
case BULE_NUM:
return BLUE;
case BLACK_NUM:
return BLACK;
default:
return null;
}
}
}
在多例这个例子中,限制了本类实例化对象的产生个数 ,如果现在要增加一种颜色,就违背了开闭原则。
所以有了枚举类型,在扩展的时候,直接在枚举类中添加,不违背开闭原则。
枚举的一些特性:
- 枚举类型不能被用户实例化;
- 定义枚举对象(通常名字是大写)
- 使用枚举对象,通过枚
枚类.属性
- 枚举类型就是典型的多例设计,每个枚举对象有且只有一个。
举例:使用枚举
enum Color{
//private final static Color RED = new Color();
RED,BLUE,BLACK;
}
public class TestColor {
public static void main(String[] args) {
//Color color = new Color(); 枚举类型不能被实例化
Color color = Color.RED; //取得红色对象
Color color1 = Color.RED;
System.out.println(Color.RED); //RED
System.out.println(color == color1); //true
}
}
枚举就是一种高级的多例设计模式。
2. Enum类
虽然JDK1.5提供了enum
关键字,但是enum并不是一种新的结构,它是对一种类型的包装。
使用enum关键字定义的枚举类本质上就相当于一个Class定义的类,继承了java.lang.Enum
父类。
在Enum中有很多方法,以下简单说明几种:
(1)构造方法
protected Enum(String name, int ordinal)
(2)取得枚举对象的名称
public final String name()
(3)取得枚举序号
public final int ordinal()
(4)获取枚举对象(枚举常量),name必须要存在
public static valueOf(String name)
举例:使用上述方法
enum Color{
//private final static Color RED = new Color();
RED,BLUE,BLACK;
}
public class TestColor {
public static void main(String[] args) {
//列举所有枚举对象,返回一个枚举对象的数组
Color[] colors = Color.values();
for (Color c:colors){
System.out.println(c.name());
}
Color color = Color.valueOf("RED");
System.out.println(color); //RED
System.out.println(color.ordinal()); //0
}
}
enum和Enum的区别:
enum是一个关键字,使用enum定义的枚举类本质上就相当于一个类继承了Enum这个抽象类而已。
3. 定义结构
枚举和普通类有很多相似的地方,可以定义成员属性,静态属性和成员方法。
举例:在枚举类中定义属性和方法
enum Color{
//在构造方法中有了属性,枚举对象中也必须包含
RED("#0000FF"),BLUE("#00FF11"),BLACK("#000000");
private String rgb;
//枚举类的构造方法是私有的
Color(String rgb) {
this.rgb = rgb;
}
//一般不提供setter方法,不建议修改,因为保证枚举对象是唯一的
public String getRgb() {
return rgb;
}
public void print(){
System.out.println(this+" :颜色的RGB:" +this.getRgb());
}
@Override
public String toString() {
return "Color{" +
"rgb='" + rgb + '\'' +
'}';
}
}
public class TestColor {
public static void main(String[] args) {
Color color = Color.RED;
System.out.println(color);
Color.BLACK.print();
}
}
举例:枚举类实现接口
interface IColor{
void getRGB();
}
enum Color implements IColor{
//在构造方法中有了属性,枚举对象中也必须包含
RED("#0000FF"),BLUE("#00FF11"),BLACK("#000000");
private String rgb;
private Color(String rgb) {
this.rgb = rgb;
}
@Override
public void getRGB() {
System.out.println(this.rgb);
}
@Override
public String toString() {
return "Color{" +
"rgb='" + rgb + '\'' +
'}';
}
}
public class TestColor {
public static void main(String[] args) {
Color color = Color.RED;
color.getRGB();
//java.lang.Enum 得到枚举类的父类
System.out.println(Color.class.getSuperclass().getName());
}
}
上面已经实现了一个接口,可以继续继承其他类吗?
- 不可以,因为该枚举类已经继承了java.lang.Enum(隐式继承),Java中支持单继承。
4. 枚举类的应用
枚举类的最大特点是只指定的几个对象可以使用。
比如:性别如果定义一个普通类就可以随便实例化,但是性别只有两种(一般只有两种,这里不严谨 ?),所以采用枚举类。
举例:定义一个表示性别的枚举类,只能有两个对象。
public enum Gender {
MALE("男"),
FAMEALE("女");
private String flag;
private Gender(String flag){
this.flag = flag;
}
public String getFlag() {
return flag;
}
}
public class Person {
private String name;
private int age;
private Gender gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Gender getGender() {
return gender;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender.getFlag() +
'}';
}
}
public class TestPerson {
public static void main(String[] args) {
Person person = new Person();
person.setName("张三");
person.setAge(20);
person.setGender(Gender.MALE);
System.out.println(person);
}
}
举例:switch使用枚举
枚举类型还支持switch判断。
enum Gender{
MALE,
FAMALE;
}
public class TestPerson {
public static void main(String[] args) {
switch (Gender.MALE){
case MALE:
System.out.println("男人");
break;
case FAMALE:
System.out.println("女人");
break;
default:
System.out.println("未知");
}
}
}