面向对象通识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(){}//构造器重载@Overridepublic 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"){//匿名内部类的类体@Overridepublic void info(){System.out.println("理性");}},FAMALE("woman"){//匿名内部类的类体@Overridepublic void info(){System.out.println("非理性");}};abstract void info();private String dec;private Sex(String dec){this.dec=dec;}}
