面向对象通识21(枚举)
定义
枚举是实例数量已经固定的类
推论:枚举可以更好地实现单例模式
语法格式
[public] abstract|final enum 枚举名(){
//要在第一行列出所有的实例——以后就只使用这些实例
//五大成员
}
public
修饰符可以没有,abstract
和final
修饰符必然存在一个
枚举与普通类的语法区别
- 枚举默认继承
Enum
这个类,枚举不能继承其他类 - 枚举要么是
final
类,要么是abatract
类- 如果没有添加抽象方法,那系统默认该类为
final
类 - 如果有添加抽象方法,系统默认该类为
abatract
类 - 这两个修饰符为系统编译的时候自动添加,不允许开发者自行添加
- 如果没有添加抽象方法,那系统默认该类为
- 枚举类的构造器必然存在
private
修饰符,系统自动添加 - 枚举不能创建对象,枚举固定了实例
其他的,与类基本相同
枚举的功能
- 定义变量
- 调用类方法或类变量
枚举的再带方法与switch
调用枚举
定义枚举之后,枚举自动拥有如下方法
static 枚举名[] values()
:该方法返回所有的枚举实例;static 枚举名 valueOf(String names)
:该方法根据枚举名返回枚举实例String name()
:该方法返回枚举实例的名字int Ordinal()
:该方法返回枚举实例的序号
switch
表达式类型——int\short\byte\String\enum
举例:
public enum Season {
spring,summer,autumn,winter;
public void info(){
//this带表对象是season实例
switch (this){
case spring:
System.out.println("Sp");
break;
case summer:
System.out.println("Su");
break;
case autumn:
System.out.println("Au");
break;
case winter:
System.out.println("Wi");
break;
}
}
}
public class SeasonTest {
public static void main(String[] args) {
//对于枚举,直接用已有的实例赋值
Season s1=Season.spring;
System.out.println(s1.name());
System.out.println(s1.ordinal());
Season[] ss=Season.values();
for (Season s2:ss){
System.out.println(s2);
}
String str="summer";
//根据字符串名称返回对应的枚举实例
Season s3=Season.valueOf(str);
s3.info();
}
}
枚举定义构造器
枚举类的第一行是创建并列出枚举类的所有实例——因此需要构造器来传入对应的参数
public enum Orientation {
//枚举的第一行并不仅仅是简单的列出枚举实例
//实际上是四个public static final修饰的常量
//最终目的是创建并列出所有枚举类的所有实例
NORTH("北"),SOUTH,WEST("西"),EAST("东");
//调用无参构造器与调用String参数的构造器
private String desc;
Orientation(String desc){
this.desc=desc;
}
Orientation(){
}//构造器重载
@Override
public String toString(){
return "Orientation[desc="+this.desc+"]";
}
}
public class OrientationTest {
public static void main(String[] args) {
Orientation o1=Orientation.NORTH;
System.out.println(o1);
}
}
/*
Orientation[desc=北]
*/
抽象枚举和实现接口的枚举
- 枚举要求在第一行创建并且列出所有的枚举实例
- 但抽象类不能创建实例
——矛盾!
得出浅层结论:枚举不能是抽象类
实现抽象枚举
(见前文)如果枚举内含有抽象方法,系统会自动给枚举添加修饰符abstract
,
此时需要使用匿名内部类在枚举的第一行创建枚举实例
如果调用了有参数的构造器,匿名内部类的参数要与之对应
枚举可以是抽象的!
public enum Sex {
MALE("man"){
//匿名内部类的类体
@Override
public void info(){
System.out.println("理性");
}
},
FAMALE("woman"){
//匿名内部类的类体
@Override
public void info(){
System.out.println("非理性");
}
};
abstract void info();
private String dec;
private Sex(String dec){
this.dec=dec;
}
}