JAVA面向对象学习——java面向对象概念———Java 枚举(enum)
Java 枚举(enum)
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。
例如定义一个颜色的枚举类。
enum Color
{
RED, GREEN, BLUE;
}
以上枚举类 Color 颜色常量有 RED, GREEN, BLUE,分别表示红色,绿色,蓝色。
使用实例:
enum Color
{
RED, GREEN, BLUE;
}
public class Test2
{
// 执行输出结果
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
}
}
====================================================
内部类中使用枚举
枚举类也可以声明在内部类中:
public class Test2
{
enum Color
{
RED, GREEN, BLUE;
}
// 执行输出结果
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
}
}
每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。
以上的枚举类 Color 转化在内部类实现:
class Color
{
public static final Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();
}
迭代枚举元素
可以使用 for 语句来迭代枚举元素:
enum Color
{
RED, GREEN, BLUE;
}
public class Test2
{
public static void main(String[] args)
{
for (Color myVar : Color.values())
{
System.out.println(myVar);
}
}
}
在 switch 中使用枚举类
枚举类常应用于 switch 语句中:
enum Color
{
RED, GREEN, BLUE;
}
public class Test2
{
public static void main(String[] args)
{
Color myVar = Color.BLUE;
switch(myVar) {
case RED:
System.out.println("红色");
break;
case GREEN:
System.out.println("绿色");
break;
case BLUE:
System.out.println("蓝色");
break;
}
}
}
=============================================================
values(), ordinal() 和 valueOf() 方法
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
- values() 返回枚举类中所有的值。
- ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf()方法返回指定字符串值的枚举常量。
enum Color
{
RED, GREEN, BLUE;
}
public class Test2
{
public static void main(String[] args)
{
// 调用 values()
Color[] arr = Color.values();
// 迭代枚举
for (Color col : arr)
{
// 查看索引
System.out.println(col + " at index " + col.ordinal());
}
// 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
System.out.println(Color.valueOf("RED"));
// System.out.println(Color.valueOf("WHITE"));
}
}
=========================================================
枚举类成员
枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。
枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
enum Color
{
RED, GREEN, BLUE;
private Color()
{
System.out.println("Constructor called for : " + this.toString());
}
public void colorInfo()
{
System.out.println("Universal Color");
}
}
public class Test2
{
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
c1.colorInfo();
}
}
enum Color
{
RED, GREEN, BLUE;
private Color()
{
System.out.println("Constructor called for : " + this.name());
}
public void colorInfo()
{
System.out.println("Universal Color");
}
}
public class Test2
{
public static void main(String[] args)
{
Color c1 = Color.GREEN;
System.out.println(c1.name());
System.out.println(c1);
c1.colorInfo();
System.out.println(c1.toString());
System.out.println(c1.ordinal());
}
}
enum Color
{
RED, GREEN, BLUE;
public void colorInfo()
{
System.out.println("Universal Color");
}
}
public class Test2
{
public static void main(String[] args)
{
Color c1 = Color.GREEN;
System.out.println(c1.name());
System.out.println(c1);
c1.colorInfo();
System.out.println(c1.toString());
System.out.println(c1.ordinal());
}
}
==============================================
枚举类中的抽象方法实现,需要枚举类中的每个对象都对其进行实现。
enum Color{
RED{
public String getColor(){//枚举对象实现抽象方法
return "hong se ";
}
},
GREEN{
public String getColor(){//枚举对象实现抽象方法
return "lv se";
}
},
BLUE{
public String getColor(){//枚举对象实现抽象方法
return "lan se";
}
};
public abstract String getColor();//定义抽象方法
}
public class Test2
{
public static void main(String[] args)
{
for (Color c:Color.values()){
System.out.print(c.getColor() + "-------");
}
}
}
=================================================================
=================================================================
枚举类
Java 5新增了一个enum关键字(它与class、interface关键字的地位相同),用以定义枚举类。
正如前面看到的,枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或者多个接口,也可以定义自己的构造器。
一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须和该枚举类的类名相同。
但枚举类终究不是普通类,它与普通类有如下简单区别:
? 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是默认继承Object类,因此枚举类不能显式继承其他父类。
其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
? 使用enum定义、非抽象的枚举类默认会使用final修饰。
? 枚举类的构造器只能使用private访问控制符,如果省略了构造器的访问控制符,则默认使用private修饰;
如果强制指定访问控制符,则只能指定private修饰符。由于枚举类的所有构造器都是private的,而子类构造器总要调用父类构造器一次,因此枚举类不能派生子类。
? 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无须程序员显式添加。
枚举类默认提供了一个values()方法,该方法可以很方便地遍历所有的枚举值。
public enum SeasonEnum
{
// 在第一行列出4个枚举实例
SPRING, SUMMER, FALL, WINTER;
}
public class EnumTest
{
public void judge(SeasonEnum s)
{
// switch语句里的表达式可以是枚举值
switch (s)
{
case SPRING:
System.out.println("春暖花开,正好踏青");
break;
case SUMMER:
System.out.println("夏日炎炎,适合游泳");
break;
case FALL:
System.out.println("秋高气爽,进补及时");
break;
case WINTER:
System.out.println("冬日雪飘,围炉赏雪");
break;
}
}
public static void main(String[] args)
{
// 枚举类默认有一个values方法,返回该枚举类的所有实例
for (var s : SeasonEnum.values())
{
System.out.println(s);
}
// 使用枚举实例时,可通过EnumClass.variable形式来访问
new EnumTest().judge(SeasonEnum.SPRING);
}
}
public class EnumTest
{
public void judge(SeasonEnum s)
{
switch (s)
{
case SPRING:
System.out.println("1");
break;
case SUMMER:
System.out.println("2");
break;
case FALL:
System.out.println("3");
break;
case WINTER:
System.out.println("4");
break;
}
}
public static void main(String[] args)
{
System.out.println("------------------");
for (SeasonEnum s : SeasonEnum.values())
{
System.out.println(s);
}
System.out.println("------------------");
new EnumTest().judge(SeasonEnum.SPRING);
}
}
枚举类的成员变量、方法、构造器
枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以定义成员变量、方法、构造器。
public enum Gender
{
MALE, FEMALE;
// 定义一个public修饰的实例变量
public String name;
}
public class GenderTest
{
public static void main(String[] args)
{
// 通过Enum的valueOf()方法来获取指定枚举类的枚举值
Gender g = Enum.valueOf(Gender.class, "FEMALE");
// 直接为枚举值的name实例变量赋值
g.name = "女";
// 直接访问枚举值的name实例变量
System.out.println(g + "代表:" + g.name);
}
}
----------------------------------------------------------------------------------------------------------------------------------------------
public enum Gender
{
MALE, FEMALE;
private String name;
public void setName(String name)
{
switch (this)
{
case MALE:
if (name.equals("男"))
{
this.name = name;
}
else
{
System.out.println("参数错误");
return;
}
break;
case FEMALE:
if (name.equals("女"))
{
this.name = name;
}
else
{
System.out.println("参数错误");
return;
}
break;
}
}
public String getName()
{
return this.name;
}
}
public class GenderTest
{
public static void main(String[] args)
{
Gender g = Gender.valueOf("FEMALE");
g.setName("女");
System.out.println(g + "代表:" + g.getName());
// 此时设置name值时将会提示参数错误。
g.setName("男");
System.out.println(g + "代表:" + g.getName());
}
}
public enum Operation
{
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;
}
},
DIVIDE
{
public double eval(double x, double y)
{
return x / y;
}
};
// 为枚举类定义一个抽象方法
// 这个抽象方法由不同的枚举值提供不同的实现
public abstract double eval(double x, double y);
public static void main(String[] args)
{
System.out.println(Operation.PLUS.eval(3, 4));
System.out.println(Operation.MINUS.eval(5, 4));
System.out.println(Operation.TIMES.eval(5, 4));
System.out.println(Operation.DIVIDE.eval(5, 4));
}
}
枚举类里面定义抽象方法时,不能使用abstract关键字将枚举类定义为抽象类(因为系统会自动为它添加abstract关键字);
但是因为枚举类需要显式创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则错误。