题外话:
1、要想在每次new一个新类或其他时,显示一些信息,
则可以:
设置--->编辑器--->文件和代码模板--->Include--->输入信息即可
2、增强for循环
int[] nums={1,2,9};
//普通的for循环
for(int i=0;i<nums.length;i++){
System.out.println(nums[i]);
}
//增强for循环
for(int i:nums){//执行流程:依次从nums数组中取出数据,赋给i,如果取出完毕,则退出
System.out.println("i="+i);
}
一、基本介绍:
1、枚举enumeration,简写enum
2、枚举是一组常量的集合
3、枚举属于一种特殊的类,里面只包含一组有限的特定的对象
二、两种实现方式:
1、自定义类实现枚举
(1)不需要提供setXxx方法,因为枚举对象值通常为只读
(2)对枚举对象/属性使用final+static共同修饰,实现底层优化
(3)枚举对象名通常使用全部大写,常量的命名规范
(4)枚举对象根据需要,也可以有多个属性
单例设计模式核心是只有一个对象,饿汉式的构造私有化,创建私有静态对象和创造公共方法都是为了实现只创建一个对象,而枚举的目标是限制访问已有的有限个对象
package enum_;
public class Enumeration02 {
public static void main(String[] args) {
System.out.println(Season.AUTUMN );
}
}
class Season{
private String name;
private String desc;//描述
public static Season SPRING=new Season("春天","温暖");
public static Season WINTER=new Season("冬天","寒冷");
public static Season AUTUMN=new Season("秋天","凉爽");
public static Season SUMMER=new Season("夏天","炎热");
//1、将构造器私有化,目的是防止直接new
//2、去年setXxx方法,防止属性被修改
//3、在Season内部,直接创建固定的对象
//4、优化,加final修饰符,final+static配合起来,底层优化了,不需要加载类了
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public static Season getSPRING() {
return SPRING;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
//输出:Season{name='秋天', desc='凉爽'}
(5)特点:
1)构造器私有化
2)本类内部创建一组对象
3)对外暴露对象(通过为对象添加public final static修饰符)
4)可以提供get方法,但不要提供set方法
2、使用enum关键字实现枚举
(1)当我们使用enum关键字开发一个枚举类时,默认会继承Enum类
(2)传统的public static Season SPRING=new Season("春天","温暖");简化成SPRING("春天","温暖");
必须要知道,它调用的是哪个构造器
(3)如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
(4)当有多个枚举对象时,使用逗号间隔,最后有一个分号结尾
(5)枚举对象必须放在枚举类的最前面
package enum_;
public class Enumeration02 {
public static void main(String[] args) {
System.out.println(Season.AUTUMN );
}
}
enum Season{
//1、使用关键字enum替代class
//2、public static Season SPRING=new Season("春天","温暖");直接使用SPRING("春天","温暖");替代
//常量名(实参列表)
//3、如果有多个常量(对象),使用","号间隔
//4、将定义的常量对象写在最前面
//5、如果我们使用的是无参构造器,创建常量对象,则可以省略括号()
SPRING("春天","温暖"),WINTER("冬天","寒冷"),
AUTUMN("秋天","凉爽"),SUMMER("夏天","炎热"),What;
private String name;
private String desc;
private Season(){}//无参构造器
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public static Season getSPRING() {
return SPRING;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
//输出:Season{name='秋天', desc='凉爽'}
(6)例题:
1)
enum Gender{
BOY,GIRL;
}
//正确,
//有一个枚举类Gender,没有属性
//有两个枚举对象BOY,GIRL,使用的是无参构造器创建
2)
package enum_;
public class Enumeration02 {
public static void main(String[] args) {
Gender boy =Gender.BOY;
Gender boy2 =Gender.BOY;
System.out.println(boy);
//本质就是调用Gender的父类Enum的toString():
//public String toString(){
// return name;
//}
//输出boy会去找toString()方法,而Gender没有就会去找父类的,
//而父类的只会返回枚举常量的名字
System.out.println(boy==boy2);
}
}
enum Gender{
BOY,GIRL;
}
//输出:
//BOY
//true
三、enum常用方法说明
1、使用关键字enum时,会隐式继承Enum,这样我们就可以使用Enum类相关的方法
//源码定义
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable{
}
//演示Enum类的各种方法
package enum_;
public class EnumMethod {
public static void main(String[] args) {
Season autumn=Season.AUTUMN;
//输出枚举对象的名字
System.out.println(autumn.name());
//输出:AUTUMN
//输出枚举对象的次序/编号,从0开始编号
System.out.println(autumn.ordinal());
//输出:2
//返回Season[]含有定义的所有枚举对象
Season[] values=Season.values();
for(Season season:values){
System.out.println(season);
}
//输出:
//Season{name='春天', desc='温暖'}
//Season{name='冬天', desc='寒冷'}
//Season{name='秋天', desc='凉爽'}
//Season{name='夏天', desc='炎热'}
//将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常
Season autumn1=Season.valueOf("AUTUMN");
System.out.println("autumn1="+autumn1);
System.out.println(autumn==autumn1);
//执行流程:
//1、根据你输入的"AUTUMN"到Season的枚举对象去查找
//2、如果找到了就返回,否则报错
//输出:
//autumn1=Season{name='秋天', desc='凉爽'}
//true
//比较两个枚举常量,比较的就是编号
System.out.println(Season.AUTUMN.compareTo(Season.SUMMER));
//执行流程:把Season.AUTUMN枚举对象的编号和Season.SUMMER枚举对象的编号比较
//源码:public final int compareTo(E o) {
// return self.ordinal - other.ordinal;
// }
//输出:-1//即为2-3=-1
}
}
enum Season{
SPRING("春天","温暖"),WINTER("冬天","寒冷"),
AUTUMN("秋天","凉爽"),SUMMER("夏天","炎热");
private String name;
private String desc;
private Season(){}
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public static Season getSPRING() {
return SPRING;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
练习题:
//我的代码:
package enum_;
public class EnumExercise02 {
public static void main(String[] args) {
System.out.println("===所有星期的信息如下===");
Week[] values=Week.values();
for(Week week:values){
System.out.println(week);
}
}
}
enum Week{
MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),
THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");
private String name;
Week(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
//输出:
//===所有星期的信息如下===
//星期一
//星期二
//星期三
//星期四
//星期五
//星期六
//星期日
//改进:
getName()和重写toString()都是返回名字的,保留一个就行
四、enum实现接口
1、使用enum关键字后,就不能再继承其它类了,因为enum会隐式继承Enum,而java是单继承机制
2、枚举类仍然是一个类,所以还是可以实现接口,如下形式:
enum 类名 implements 接口1,接口2{}
package enum_;
public class EnumDetail {
public static void main(String[] args) {
Music.CLASSICMUSIC.playing();
}
}
interface IPlaying{
public void playing();
}
enum Music implements IPlaying{
CLASSICMUSIC;
public void playing(){
System.out.println("播放好听的音乐");
}
}
//输出:播放好听的音乐