Java面向对象(高级)-- 枚举类的使用

文章目录

  • 一、概述
  • 二、定义枚举类
    • (1)定义枚举类(JDK5.0 之前)
      • 1. 案例
      • 2. 分析
      • 3. 代码
    • (2) 定义枚举类(JDK5.0 之后)
      • 1. enum关键字声明枚举
      • 2. 举例
      • 3. 默认父类
      • 4. Enum中常用方法
        • 4.1 toString()
        • 4.2 name()
        • 4.3 values()
        • 4.4 valuesOf(String objName)
        • 4.5 ordinal()
      • 5. enum方式定义的要求和特点
  • 三、 枚举类实现接口的操作
    • (1)实现接口的枚举类
    • (2)情景一
    • (3)情景二
    • (4)代码
      • 4.1 SeasonTest1
      • 4.2 SeasonTest2
  • 四、练习
    • (1)练习1
    • (2)练习2
    • (3)练习3
    • (4)练习4

一、概述

  • 理解:枚举类型本质上也是一种,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建。
  • 枚举类的例子举不胜举:
    • 星期:Monday(星期一)…Sunday(星期天)
    • 性别:Man(男)、Woman(女)
    • 月份:January(1月)…December(12月)
    • 季节:Spring(春节)…Winter(冬天)
    • 三原色:red(红色)、green(绿色)、blue(蓝色)
    • 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)
    • 就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)
    • 订单状态:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、Delivered(已发货)、Checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)
    • 线程状态:创建、就绪、运行、阻塞、死亡
  • 若枚举只有一个对象, 则可以作为一种单例模式的实现方式。
  • 枚举类的实现:
    • 在JDK5.0 之前,需要程序员自定义枚举类型。
    • 在JDK5.0 之后,Java支持enum关键字来快速定义枚举类型。
  • 开发中的建议:

① 开发中,如果针对于某个类,其实例(对象)是确定个数的。则推荐将此类声明为枚举类。

② 如果枚举类的实例只有一个,则可以看做是单例的实现方式。

二、定义枚举类

(1)定义枚举类(JDK5.0 之前)

JDK5.0之前如何声明枚举类呢?手动定义枚举类,通过class的方式定义枚举类。

  • 私有化类的构造器,保证不能在类的外部创建其对象
  • 在类的内部创建枚举类的实例。声明为:public static final ,对外暴露这些常量对象
  • 对象如果有实例变量,应该声明为private final(建议,不是必须),并在构造器中初始化

1. 案例

季节:Spring(春节)…Winter(冬天)

将Season定义为“枚举类”。

public class SeasonTest {

}

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的

}

2. 分析

🎲分析

<1> 限制构造器

Season是枚举类,它的对象个数是确定的,所以先搞定构造器的问题,若是构造器对外暴露,那么外面就可以随意创建对象了。

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的
    //1.私有化类的构造器
    private Season(){

    }
}

<2> 声明当前类的对象的实例变量

前面讲单例的时候,没有提供关于对象的实例变量,这里提供一下。

比如季节要造四个对象,每个季节对象都有一个或者两个实例的变量,就先在前面声明一下。

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的
    //声明当前类的对象的实例变量
    String seasonName;  //季节名称
    String seasonDesc;  //季节描述

    //1.私有化类的构造器
    private Season(){

    }
}

这里定义了两个实例变量,再给这两个实例变量一些修饰。

比如造对象的时候,就将属性赋值了,只让外面获取值而不能修改值(final)。

而且获取是通过方法来获得,所以这两个变量要私有化(private)。

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的
    //声明当前类的对象的实例变量
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述

    //1.私有化类的构造器
    private Season(){

    }
}

注意不能加static,加了static就表示它们都共用了,显然这里不能共用。

上面声明完之后,因为是final的,所以要对应“显示初始化”或者“构造器”或者“代码块”来给它赋值。

这里咱们选择在构造器中将它初始化。

如下:

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的
    //2.声明当前类的对象的实例变量
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述

    //1.私有化类的构造器
    private Season(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }
}

如果针对当前类的多个实例,要是有实例变量的话,就给它声明一下,一定要注意它的修饰。

<3> 提供实例变量的get方法

既然上面提供了相应的属性并私有化了,那如果外部想看一下具体对象的值的话,这里就需要提供相应的get方法。

如下:

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的

    //3. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}

<4> 创建当前类的实例

接下来在类的内部创建对象。

如下:

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的

    //4.创建当前类的实例
    Season spring=new Season("春天","春暖花开");
    Season summer=new Season("夏天","夏日炎炎");  //Ctrl+D可以快速复制上一行的代码
    Season autumn=new Season("秋天","秋高气爽");
    Season winter=new Season("冬天","白雪皑皑");

}

有几个注意点。

①这几个对象在类的外部可以使用,但是不能够修改。

使用的话,在类的外部直接调用,没必要再通过方法了(不再提供对象的get方法)。

所以这里直接就可以public。比如:public Season spring=new Season("春天","春暖花开");

②此时spring是当前类的一个对象,在外面需要拿去调用。

而现在它不是静态的,得拿对象来调,但此时它就是一个对象啊。目的是为了拿到它,现在还要用它去调,这就矛盾了。

所以此时这个对象还要加一个static,这样就可以直接在类的外部用类来调用

比如:public static Season spring=new Season("春天","春暖花开");

image.png

③现在还有一个问题,这个对象可以使用,但是不能更改

虽然这里外部看不到构造器,如下:

image.png

但是也不能更改null

image.png

既然不能让它更改,那么还需要final一下,比如:public static final Season spring=new Season("春天","春暖花开");

所以最终这些实例都需要这样来修饰:public static final

如下:

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的

    //4.创建当前类的实例
    public static final Season spring=new Season("春天","春暖花开");
    public static final Season summer=new Season("夏天","夏日炎炎");  //Ctrl+D可以快速复制上一行的代码
    public static final Season autumn=new Season("秋天","秋高气爽");
    public static final Season winter=new Season("冬天","白雪皑皑");

}

可以看到,刚才的地方就会报错了:

image.png

既然这里是全局常量了,那么大写比较合适,如下:

//4.创建当前类的实例
public static final Season SPRING=new Season("春天","春暖花开");
public static final Season SUMMER=new Season("夏天","夏日炎炎");  
public static final Season AUTUMN=new Season("秋天","秋高气爽");
public static final Season WINTER=new Season("冬天","白雪皑皑");

最后,还可以提供一个toString方法,方便在调用对象的时候看一看相应属性的值。

//toString方法
@Override
public String toString() {
    return "Season{" +
    "seasonName='" + seasonName + '\'' +
    ", seasonDesc='" + seasonDesc + '\'' +
    '}';
}

3. 代码

所以,jdk5.0之前枚举类就是这样写的:

🌱代码

package yuyi02;

/**
 * ClassName: SeasonTest
 * Package: yuyi02
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/3 0003 8:57
 */
public class SeasonTest {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);  //打印
        
        System.out.println(Season.SUMMER.getSeasonName());
        System.out.println(Season.SUMMER.getSeasonDesc());
    }
}

//jdk5.0之前定义枚举类的方式
class Season{   //这个类的对象个数是有限个的
    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //1.私有化类的构造器
    private Season(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //3. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //4.创建当前类的实例,需要使用 public static final修饰
    public static final Season SPRING=new Season("春天","春暖花开");
    public static final Season SUMMER=new Season("夏天","夏日炎炎");  //Ctrl+D可以快速复制上一行的代码
    public static final Season AUTUMN=new Season("秋天","秋高气爽");
    public static final Season WINTER=new Season("冬天","白雪皑皑");


    //toString方法
    @Override
    public String toString() {
        return "Season{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

🍺输出结果

image.png

(2) 定义枚举类(JDK5.0 之后)

1. enum关键字声明枚举

格式

【修饰符】 enum 枚举类名{
    常量对象列表
}

【修饰符】 enum 枚举类名{
    常量对象列表;
    
    对象的实例变量列表;
}

举例1:

package com.atguigu.enumeration;

public enum Week {
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
public class TestEnum {
	public static void main(String[] args) {
		Season spring = Season.SPRING;
		System.out.println(spring);
	}
}

2. 举例

在idea里面新建java文件,可以看到有一个Enum

image.png

这里为了方便演示,都写在一个文件里面了。

public class SeasonTest1 {

}

//jdk5.0中使用enum关键字定义枚举类
enum Season1{

}

如果按照刚才jdk5.0之前的写法,应该是这样:

enum Season1{
    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
	private final String seasonDesc;  //季节描述


    //1.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }
    
    
    //3. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }
    
    public String getSeasonDesc() {
        return seasonDesc;
    }
    
    
    //4.创建当前类的实例,需要使用 public static final修饰
    public static final Season1 SPRING=new Season1("春天","春暖花开");
    public static final Season1 SUMMER=new Season1("夏天","夏日炎炎");  //Ctrl+D可以快速复制上一行的代码
    public static final Season1 AUTUMN=new Season1("秋天","秋高气爽");
    public static final Season1 WINTER=new Season1("冬天","白雪皑皑");
    
    
    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

编译器会报错

对于enum关键字来定义的枚举类有一个要求,一上来就必须要将对象放在这。

那就将第4步挪到前面来,哎?错误更多了:

image.png

这里需要做一个调整。

以前说过“接口”,接口里面有抽象方法,抽象方法都声明为public abstract,当时说这两个关键字可以省略不写。

而对于枚举类来说,之前说过实例它们都是用public static final来声明的。

所以需要将相同的部分去除。(注意不是可以去掉,而是必须去除

同样,对象也都是Season1类型,也要去掉

后面new Season1也一样,去掉。(new的是具体的类的构造器,所以可以去除)

对象名不一样,所以不要删。

小括号也不要去除,因为里面有变量,相当于对形参赋值了,需要括一下。

下面红框部分都是要去除的:(等于号也删掉

image.png

删完之后:

SPRING("春天","春暖花开");
SUMMER("夏天","夏日炎炎");
AUTUMN("秋天","秋高气爽");
WINTER("冬天","白雪皑皑");

还要改一个地方,多个对象之间要用逗号隔开最后分号结束

所以,最终结果:

//1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","白雪皑皑");

构造器,实例变量,get方法该有还是要有。


🌱代码

//jdk5.0中使用enum关键字定义枚举类
enum Season1{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}

3. 默认父类

刚才写的例子中,枚举类Season1其实有一个默认父类。

比如我们可以获取一下当前对象所属的类及父类。

如下:

public class SeasonTest1 {
    public static void main(String[] args) {
        System.out.println(Season1.SPRING.getClass());  //获取当前对象所属的类
        System.out.println(Season1.SPRING.getClass().getSuperclass());  //获取当前对象所属类的父类
    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

}

输出结果:

image.png

所以,当前类有一个默认父类Enum

如果此时想让枚举类去继承其他类,是不可以的。

如下:

image.png

用enum关键字定义的枚举类,默认的父类已经确定好了,不要让它再去继承其他类了。

如果感兴趣,还可以看一下Enum类的父类,是Object,如下:

image.png

4. Enum中常用方法

既然枚举类都继承于Enum类,在Enum类中提供了一些方法,这里看一下它里面的方法都有哪些。

String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
    
static 枚举类型[] values():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法
    
static 枚举类型 valueOf(String name):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。
    
String name():得到当前枚举常量的名称。建议优先使用toString()。
    
int ordinal():返回当前枚举常量的次序号,默认从0开始
4.1 toString()

String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!

//1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
System.out.println(Season1.SPRING);

🌱代码

public class SeasonTest1 {
    public static void main(String[] args) {

        //测试方法
        //1.toString()
        System.out.println(Season1.SPRING);

    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}

🍺输出结果

image.png

可以发现,它默认打印当前对象的名字

如果不想让它这样打印,可以重写一下。

//toString方法
@Override
public String toString() {
    return "Season1{" +
    "seasonName='" + seasonName + '\'' +
    ", seasonDesc='" + seasonDesc + '\'' +
    '}';
}

然后再去Run,就是重写之后的了:

image.png

toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的

4.2 name()

String name():得到当前枚举常量的名称。建议优先使用toString()。

//2.name():打印当前对象的名称
System.out.println(Season1.SPRING.name());

🌱代码

public class SeasonTest1 {
    public static void main(String[] args) {

        //测试方法
        //1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
        System.out.println(Season1.SPRING);

        //2.name():打印当前对象的名称
        System.out.println(Season1.SPRING.name());

    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

🍺输出结果

image.png

name():打印当前对象的名称。

4.3 values()

static 枚举类型[] values():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法。

 //3.values():将当前枚举类所有对象都取出来
Season1[] values=Season1.values();  //静态方法,返回值是一个数组,数组就是Season1类型的

🌱代码

public class SeasonTest1 {
    public static void main(String[] args) {

        //测试方法
        //1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
        System.out.println(Season1.SPRING);

        //2.name():打印当前对象的名称
        System.out.println(Season1.SPRING.name());

        //3.values():将当前枚举类所有对象都取出来
        Season1[] values=Season1.values();  //静态方法,返回值是一个数组,数组就是Season1类型的
        //输出数组元素
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);  //打印的时候会调用toSting方法
        }

    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

🍺输出结果

image.png

values():将当前枚举类所有对象都取出来。想看当前枚举类有什么对象,就可以使用这个方法。

4.4 valuesOf(String objName)

static 枚举类型 valueOf(String name):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。

//4.valuesOf(String objName):返回当前枚举类中名称为objName的枚举类对象,如果枚举类中不存在objName名称的对象,则报错
String objName="WINTER";
Season1 season1=Season1.valueOf(objName);   //根据传进来的字符串,找到在枚举类中叫这个名字的枚举类的对象
System.out.println(season1);

🌱代码

public class SeasonTest1 {
    public static void main(String[] args) {

        //测试方法
        //1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
        System.out.println(Season1.SPRING);

        //2.name():打印当前对象的名称
        System.out.println(Season1.SPRING.name());

        //3.values():将当前枚举类所有对象都取出来
        Season1[] values=Season1.values();  //静态方法,返回值是一个数组,数组就是Season1类型的
        //输出数组元素
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);  //打印的时候会调用toSting方法
        }

        System.out.println();   //换行

        //4.valuesOf(String objName):
        String objName="WINTER";
        Season1 season1=Season1.valueOf(objName);   //根据传进来的字符串,找到在枚举类中叫这个名字的枚举类的对象
        System.out.println(season1);

    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

🍺输出结果

image.png

传进来的不是枚举类里面的值,就会报错,比如传进来了一个WINTER1,如下:

image.png

IllegalArgumentException非法参数异常

4.5 ordinal()

int ordinal():返回当前枚举常量的次序号,默认从0开始。非静态方法,需要拿对象去调用。

//5.ordinal()
System.out.println(Season1.AUTUMN.ordinal());   //打印出当前对象在枚举类中是第几个声明的对象

🌱代码

public class SeasonTest1 {
    public static void main(String[] args) {

        //测试方法
        //1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
        System.out.println(Season1.SPRING);

        System.out.println();   //换行

        //2.name():打印当前对象的名称
        System.out.println(Season1.SPRING.name());

        System.out.println();   //换行

        //3.values():将当前枚举类所有对象都取出来
        Season1[] values=Season1.values();  //静态方法,返回值是一个数组,数组就是Season1类型的
        //输出数组元素
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);  //打印的时候会调用toSting方法
        }

        System.out.println();   //换行

        //4.valuesOf(String objName):返回当前枚举类中名称为objName的枚举类对象,如果枚举类中不存在objName名称的对象,则报错
        String objName="WINTER";
        //String objName="WINTER1";     //IllegalArgumentException异常
        Season1 season1=Season1.valueOf(objName);   //根据传进来的字符串,找到在枚举类中叫这个名字的枚举类的对象
        System.out.println(season1);

        System.out.println();   //换行

        //5.ordinal()
        System.out.println(Season1.AUTUMN.ordinal());   //打印出当前对象在枚举类中是第几个声明的对象

    }
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

🍺输出结果

image.png

这几个方法重点关注values()–一共多少个,都是哪些枚举类对象和valuesOf–根据指定的名找到枚举类对象。

5. enum方式定义的要求和特点

  • 枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。
  • 列出的实例系统会自动添加 public static final 修饰。
  • 如果常量对象列表后面没有其他代码,那么“;”可以省略,否则不可以省略“;”。
  • 编译器给枚举类默认提供的是private的无参构造,如果枚举类需要的是无参构造,就不需要声明,写常量对象列表时也不用加参数
  • 如果枚举类需要的是有参构造,需要手动定义,有参构造的private可以省略,调用有参构造的方法就是在常量对象名后面加(实参列表)就可以。
  • 枚举类默认继承的是java.lang.Enum类,因此不能再继承其他的类型。
  • JDK5.0 之后switch,提供支持枚举类型,case后面可以写枚举常量名,无需添加枚举类作为限定。

举例2:

public enum SeasonEnum {
    SPRING("春天","春风又绿江南岸"),
    SUMMER("夏天","映日荷花别样红"),
    AUTUMN("秋天","秋水共长天一色"),
    WINTER("冬天","窗含西岭千秋雪");

    private final String seasonName;
    private final String seasonDesc;
    
    private SeasonEnum(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
}

举例3:

package com.atguigu.enumeration;

public enum Week {
    MONDAY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期日");

    private final String description;

    private Week(String description){
        this.description = description;
    }

    @Override
    public String toString() {
        return super.toString() +":"+ description;
    }
}
package com.atguigu.enumeration;

public class TestWeek {
    public static void main(String[] args) {
        Week week = Week.MONDAY;
        System.out.println(week);

        switch (week){
            case MONDAY:
                System.out.println("怀念周末,困意很浓");break;
            case TUESDAY:
                System.out.println("进入学习状态");break;
            case WEDNESDAY:
                System.out.println("死撑");break;
            case THURSDAY:
                System.out.println("小放松");break;
            case FRIDAY:
                System.out.println("又信心满满");break;
            case SATURDAY:
                System.out.println("开始盼周末,无心学习");break;
            case SUNDAY:
                System.out.println("一觉到下午");break;
        }
    }
}

经验之谈:

开发中,当需要定义一组常量时,强烈建议使用枚举类。

三、 枚举类实现接口的操作

(1)实现接口的枚举类

  • 和普通 Java 类一样,枚举类可以实现一个或多个接口
  • 若每个枚举值在调用实现的接口方法呈现相同的行为方式,则只要统一实现该方法即可。
  • 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式,则可以让每个枚举值分别来实现该方法

语法:

//1、枚举类可以像普通的类一样,实现接口,并且可以多个,但要求必须实现里面所有的抽象方法!
enum A implements 接口1,接口2{
	//抽象方法的实现
}

//2、如果枚举类的常量可以继续重写抽象方法!
enum A implements 接口1,接口2{
    常量名1(参数){
        //抽象方法的实现或重写
    },
    常量名2(参数){
        //抽象方法的实现或重写
    },
    //...
}

举例:

interface Info{
	void show();
}

//使用enum关键字定义枚举类
enum Season1 implements Info{
	//1. 创建枚举类中的对象,声明在enum枚举类的首位
	SPRING("春天","春暖花开"){
		public void show(){
			System.out.println("春天在哪里?");
		}
	},
	SUMMER("夏天","夏日炎炎"){
		public void show(){
			System.out.println("宁静的夏天");
		}
	},
	AUTUMN("秋天","秋高气爽"){
		public void show(){
			System.out.println("秋天是用来分手的季节");
		}
	},
	WINTER("冬天","白雪皑皑"){
		public void show(){
			System.out.println("2002年的第一场雪");
		}
	};
	
	//2. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//3. 私有化类的构造器
	private Season1(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	
	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}
}

(2)情景一

情况1:枚举类实现接口,在枚举类中重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是同一个方法
拿这个例子来说。

//jdk5.0中使用enum关键字定义枚举类
enum Season1 {
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }
}

现在创建一个接口Info,在里面写一个抽象方法show()。

interface Info{
    void show();
}

然后让枚举类Season1去实现接口Info,自然而然地需要将接口中地抽象方法重写一下(为了实例化)。

//jdk5.0中使用enum关键字定义枚举类
enum Season1 implements Info{
    //...
    @Override
    public void show() {
        System.out.println("这是一个季节");
    }
}

OK了,show()就是一个普通的方法,方法非静态,就可以在测试类SeasonTest1里面通过对象来调用它。

如下:

public class SeasonTest1 {
    public static void main(String[] args) {

        //通过枚举类的对象调用重写接口中的方法
        Season1.SUMMER.show();
        Season1.AUTUMN.show();

    }
}

interface Info{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 implements Info{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }

    @Override
    public void show() {
        System.out.println("这是一个季节");
    }
}

输出结果:

image.png

(3)情景二

情况2:让枚举类的每一个对象重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是不同的实现的方法

既然结果不一样,其实就是让每一个对象,各自重写一下这个方法。

还是刚才的代码:

public class SeasonTest2 {

}

interface Info1{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season2 implements Info1{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season2(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season2{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }

    @Override
    public void show() {
        System.out.println("这是一个季节");
    }
}

枚举类Season2实现接口Info1。

此时我们不在当前类里面重写show()方法了,而是让每个对象各自去实现抽象方法。

在这里整一对大括号,如下:

image.png

然后在这一对大括号里面重写show()方法,如下:

image.png

其他的也是类似:

//1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
SPRING("春天","春暖花开"){
    @Override
    public void show() {
        System.out.println("春天来了,万物复苏");
    }
},
SUMMER("夏天","夏日炎炎"){
    @Override
    public void show() {
        System.out.println("夏天来了,烈日炎炎");
    }
},
AUTUMN("秋天","秋高气爽"){
    @Override
    public void show() {
        System.out.println("秋天来了,秋风萧瑟");
    }
},
WINTER("冬天","白雪皑皑"){
    @Override
    public void show() {
        System.out.println("冬天来了,银装素裹");
    }
};

然后我们在main方法里面测试一下:

public class SeasonTest2 {
    public static void main(String[] args) {
        Season2[] values=Season2.values();  //将所有对象都拿到,然后存入数组values中
        for (int i = 0; i < values.length; i++) {
            values[i].show();   //用每个对象去调用show()方法,各自就调用各自重写的方法
        }
    }
}

interface Info1{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season2 implements Info1{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("春天来了,万物复苏");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        @Override
        public void show() {
            System.out.println("夏天来了,烈日炎炎");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        @Override
        public void show() {
            System.out.println("秋天来了,秋风萧瑟");
        }
    },
    WINTER("冬天","白雪皑皑"){
        @Override
        public void show() {
            System.out.println("冬天来了,银装素裹");
        }
    };


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season2(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season2{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }

}

输出结果:

image.png

其实可以将它们看作是“匿名的实现类”,因为将方法show()单独重写了,其实都是继承于当前类Season2的匿名子类。

image.png

具体细节不用深究,只需要知道可以对每个对象单独重写即可。有一些特殊场景可能会用到。

枚举类区别于单例模式,就是它的对象不止一个,有几个造几个。

(4)代码

4.1 SeasonTest1

【SeasonTest1.java】

package yuyi02;

/**
 * ClassName: SeasonTest1
 * Package: yuyi02
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/3 0003 10:03
 */
public class SeasonTest1 {
    public static void main(String[] args) {
        /*System.out.println(Season1.SPRING.getClass());  //获取当前对象所属的类
        System.out.println(Season1.SPRING.getClass().getSuperclass());  //获取当前对象所属类的父类

        System.out.println(Season1.SPRING.getClass().getSuperclass().getSuperclass());  //获取当前对象所属类的父类的父类*/

        //测试方法
        //1.toString():没有重写的时候打印当前对象的名称,重写的话打印的就是重写之后的
        System.out.println(Season1.SPRING);

        System.out.println();   //换行

        //2.name():打印当前对象的名称
        System.out.println(Season1.SPRING.name());

        System.out.println();   //换行

        //3.values():将当前枚举类所有对象都取出来
        Season1[] values=Season1.values();  //静态方法,返回值是一个数组,数组就是Season1类型的
        //输出数组元素
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);  //打印的时候会调用toSting方法
        }

        System.out.println();   //换行

        //4.valuesOf(String objName):返回当前枚举类中名称为objName的枚举类对象,如果枚举类中不存在objName名称的对象,则报错
        String objName="WINTER";
        //String objName="WINTER1";     //IllegalArgumentException异常
        Season1 season1=Season1.valueOf(objName);   //根据传进来的字符串,找到在枚举类中叫这个名字的枚举类的对象
        System.out.println(season1);

        System.out.println();   //换行

        //5.ordinal()
        System.out.println(Season1.AUTUMN.ordinal());   //打印出当前对象在枚举类中是第几个声明的对象

        System.out.println();   //换行

        //通过枚举类的对象调用重写接口中的方法
        Season1.SUMMER.show();
        Season1.AUTUMN.show();

    }
}

interface Info{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season1 implements Info{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"),
    SUMMER("夏天","夏日炎炎"),
    AUTUMN("秋天","秋高气爽"),
    WINTER("冬天","白雪皑皑");


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season1{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }

    @Override
    public void show() {
        System.out.println("这是一个季节");
    }
}

🍺输出结果

image.png

4.2 SeasonTest2

【SeasonTest2.java】

package yuyi05;

/**
 * ClassName: SeasonTest2
 * Package: yuyi05
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/4 0004 14:37
 */
public class SeasonTest2 {
    public static void main(String[] args) {
        Season2[] values=Season2.values();  //将所有对象都拿到,然后存入数组values中
        for (int i = 0; i < values.length; i++) {
            values[i].show();   //用每个对象去调用show()方法,各自就调用各自重写的方法
        }
    }
}

interface Info1{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season2 implements Info1{
    //1.必须在枚举类的开头声明多个对象,对象之间使用逗号隔开
    SPRING("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("春天来了,万物复苏");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        @Override
        public void show() {
            System.out.println("夏天来了,烈日炎炎");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        @Override
        public void show() {
            System.out.println("秋天来了,秋风萧瑟");
        }
    },
    WINTER("冬天","白雪皑皑"){
        @Override
        public void show() {
            System.out.println("冬天来了,银装素裹");
        }
    };


    //2.声明当前类的对象的实例变量,需要使用 private final修饰
    private final String seasonName;  //季节名称
    private final String seasonDesc;  //季节描述


    //3.私有化类的构造器
    private Season2(String seasonName,String seasonDesc){
        this.seasonName=seasonName;
        this.seasonDesc=seasonDesc;
    }


    //4. 提供实例变量的get方法
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


    //toString方法
    @Override
    public String toString() {
        return "Season2{" +
        "seasonName='" + seasonName + '\'' +
        ", seasonDesc='" + seasonDesc + '\'' +
        '}';
    }

}

🍺输出结果

image.png

四、练习

(1)练习1

🌋题目描述

员工就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)

☕分析

员工的状态Status可以声明为枚举类,他有几种状态是确定的,不用在造Employee的时候再去new具体的Status了,就那几种状态,提前造好,直接拿来用即可。

上面我们举例的SeasonTest1中,枚举类Season1,每个季节都有两个实例变量,现在的情况是没有变量的,这个类就只有一个空参的构造器了,而空参构造器可以省略不写,同样也不会有实例变量的get/set方法,toString暂时也不需要。

所以一上来就只有几个对象,这几个对象里面也没有具体参数,小括号其实也可以省略。

所以最终看到的就是这样:

public enum Status {    //员工的状态可以声明为枚举类
    BUSY,FREE,VOCATION,DIMISSION;
}

直接实例化了四个对象而不是写了四个字符串值,使用的时候可以直接拿对象的变量名去使用,比定义四个字符串的写法简洁。

🌱代码

【Status.java】

package yuyi06.apply;

/**
 * ClassName: Status
 * Package: yuyi06.apply
 * Description: 定义员工的状态
 *              就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)
 * @Author 雨翼轻尘
 * @Create 2023/12/4 0004 15:51
 */
public enum Status {    //员工的状态可以声明为枚举类
    BUSY,FREE,VOCATION,DIMISSION;
}

【Employee.java】

package yuyi06.apply;

/**
 * ClassName: Employee
 * Package: yuyi06.apply
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/4 0004 15:49
 */
public class Employee {
    private String name;

    private int age;

    private Status status;  //枚举类Status就可以看作是一个类,它作为引用数据类型的变量,作为当前类的成员变量是没有问题的

    public Employee() {

    }

    public Employee(String name, int age, Status status) {
        this.name = name;
        this.age = age;
        this.status = status;
    }

    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 Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Employee{" +
        "name='" + name + '\'' +    //name本身是String类型,String中重写了toString,所以可以打印字符串的值
        ", age=" + age +            //age是基本数据类型,直接打印它的值
        ", status=" + status +      //status会调用它的toString,因为Status是enum类型,里面也有toString,直接打印名字
        '}';
    }
}

【EmployeeTest.java】

package yuyi06.apply;

/**
 * ClassName: EmployeeTest
 * Package: yuyi06.apply
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/4 0004 16:05
 */
public class EmployeeTest {
    public static void main(String[] args) {
        Employee e1=new Employee("Jully",21,Status.BUSY);   //枚举类直接用即可
        System.out.println(e1); //打印的时候不是e1的地址

    }
}

🍺输出结果

image.png

(2)练习2

🌋题目描述

案例:使用枚举类实现单例模式

☕分析

“枚举类”若是只有一个对象,那就可以写成“单例模式”。

这里写两种方法,jdk5.0之前的和jdk5.0的写法。

【单例模式–饿汉式】

//饿汉式
class Bank1{
    //1.私有化构造器
    private Bank1(){

    }

    //2.创建当前类的实例
    private static Bank1 instance=new Bank1();

    //3.提供get方法
    public static Bank1 getInstance(){
        return instance;
    }

}

现在改一改,刚才说枚举类的时候,不是通过方法去调的,直接拿去调用。

所以就不用再提供get方法了。

创建实例的时候,直接将private改为public,还要将创建的对象加一个final

public static final Bank1 instance=new Bank1();

对于变量instance,体现为两个角度,一个角度是获取它的值new Bank1(),一个角度就是设置它的值。

“单例模式的饿汉式”将变量私有化(private)了,所以需要提供get方法来获取它的值。

现在将它加上public了,所以出了类Bank1之后,可以来调用这个变量了。

而调用的时候有可能被赋予不合适的值,比如null:Bank1.instance=null;这就相当于没有实例了,这不合适,所以变量需要用final来修饰一下。

【jdk5.0之前】

//jdk5.0之前的使用枚举类定义单例模式
class Bank1{
    //1.私有化构造器
    private Bank1(){

    }

    //2.创建当前类的实例
    public static final Bank1 instance=new Bank1();

}

【jdk5.0】

//jdk5.0
enum Bank2{
    CPB;    //没有具体实例变量,构造器也省略了,直接写即可
}

再比如:

enum GirlFriend{
    XIAOMEI(20);

    //实例变量
    private final int age;

    private GirlFriend(int age){
        this.age=age;
    }
}

jdk5.0之前自己造的时候那些修饰就省略了,如下:

image.png

🌱代码

package yuyi06.exer1;

/**
 * ClassName: BankTest1
 * Package: yuyi06.exer1
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/4 0004 17:54
 */
public class BankTest1 {
    public static void main(String[] args) {
        System.out.println(GirlFriend.XIAOMEI); //调用XIAOMEI的toString方法,默认打印它的名字
    }
}

//jdk5.0之前的使用枚举类定义单例模式
class Bank1{
    //1.私有化构造器
    private Bank1(){

    }

    //2.创建当前类的实例
    public static final Bank1 instance=new Bank1();

}


//jdk5.0使用enum关键字定义枚举类的方式去定义单例模式
enum Bank2{
    CPB;    //没有具体实例变量,构造器也省略了,直接写即可
}


enum GirlFriend{
    XIAOMEI(20);

    //自己造(jdk5.0)
    //public static final GirlFriend XIAOLI=new GirlFriend(21);

    //实例变量
    private final int age;

    private GirlFriend(int age){
        this.age=age;
    }

}

🍺输出结果

image.png

(3)练习3

🌋题目描述

案例:颜色枚举类Color(使用enum声明)

1、声明颜色枚举类:7个常量对象:RED, ORANGE, YELLOW, GREEN, CYAN, BLUE,PURPLE;

2、在测试类中,使用枚举类,获取绿色对象,并打印对象。

🌱代码

【Color.java】

package yuyi06.exer2;

/**
 * ClassName: Color
 * Package: yuyi06.exer2
 * Description:
 *  1、声明颜色枚举类:7个常量对象:RED, ORANGE, YELLOW, GREEN, CYAN, BLUE,PURPLE;
 * @Author 雨翼轻尘
 * @Create 2023/12/5 0005 10:02
 */
public enum Color {
    RED, ORANGE, YELLOW, GREEN, CYAN, BLUE,PURPLE;
}

【ColorTest.java】

package yuyi06.exer2;

/**
 * ClassName: ColorTest
 * Package: yuyi06.exer2
 * Description:
 *   2、在测试类中,使用枚举类,获取绿色对象,并打印对象。
 * @Author 雨翼轻尘
 * @Create 2023/12/5 0005 10:04
 */
public class ColorTest {
    public static void main(String[] args) {
        System.out.println(Color.GREEN);
    }
}

🍺输出结果

image.png

(4)练习4

🌋题目描述

案例拓展:颜色枚举类(使用enum声明)

(1)声明颜色枚举类Color:

  • 声明final修饰的int类型的属性red,green,blue
  • 声明final修饰的String类型的属性description
  • 声明有参构造器Color(int red, int green, int blue,String description)
  • 创建7个常量对象:红、橙、黄、绿、青、蓝、紫,
  • 重写toString方法,例如:RED(255,0,0)->红色

(2)在测试类中,使用枚举类,获取绿色对象,并打印对象。

提示:

  • 7个常量对象的RGB值如下:
    红:(255,0,0)
    橙:(255,128,0)
    黄:(255,255,0)
    绿:(0,255,0)
    青:(0,255,255)
    蓝:(0,0,255)
    紫:(128,0,255)

7个常量对象名如下:

RED, ORANGE, YELLOW, GREEN, CYAN, BLUE,PURPLE

🌱代码

package yuyi06.exer3;

/**
 * ClassName: ColorTest
 * Package: yuyi06.exer3
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/12/5 0005 10:09
 */
public class ColorTest {
    public static void main(String[] args) {
        System.out.println(Color.GREEN);
        System.out.println(Color.CYAN);
    }
}

enum Color{
    //创建对象
    RED(255,0,0,"红色"),
    ORANGE(255,128,0,"橙色"),
    YELLOW(255,255,0,"黄色"),
    GREEN(0,255,0,"绿色"),
    CYAN(0,255,255,"青色"),
    BLUE(0,0,255,"蓝色"),
    PURPLE(128,0,255,"紫色");


    //属性
    private final int red;

    private final int green;

    private final int blue;

    public final String description;    //颜色的描述

    Color(int red, int green, int blue, String description) {   //构造器加上private或者不加都可以,其实就是私有的,这是enum关键字在起作用(若试图将它写成public就会报错)
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.description = description;
    }

    public int getRed() {
        return red;
    }

    public int getGreen() {
        return green;
    }

    public int getBlue() {
        return blue;
    }

    public String getDescription() {
        return description;
    }

    //重写toString方法
    @Override
    public String toString() {
        //return super.toString()+"("+red+","+green+","+blue+")->"+description;     //第一种写法 super.toString()
        return name()+"("+red+","+green+","+blue+")->"+description;     //第二种写法 name()
    }
}

🍺输出结果

image.png

🎲注意

构造器加上private或者不加都可以,其实就是私有的,这是enum关键字在起作用(若试图将它写成public就会报错)

Color(int red, int green, int blue, String description) {   //构造器加上private或者不加都可以,其实就是私有的,这是enum关键字在起作用(若试图将它写成public就会报错)
    this.red = red;
    this.green = green;
    this.blue = blue;
    this.description = description;
}

若此时枚举类里面没有对象,这里会自动加上一个分号,意思是当前没有对象,如下:

image.png

若将这个分号去掉,就会报错:

image.png

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/218756.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

辛普森距离(SD,Sampson Distance)

定义 Sampson误差是复杂性介于代数误差和几何误差之间&#xff0c;但非常近似于几何误差的一种误差。 应用 SLAM对极几何中使用到SD来筛选内点&#xff1a; 1.随机采样8对匹配点 2.8点法求解基础矩阵 ​&#xff1b; 3.奇异值约束获取基础矩阵F&#xff1b; 4.计算误差&…

在cmd下查看当前python的版本

在cmd窗口下运行python --version或者py --version&#xff0c;可以查看当前python的版本。例如&#xff1a;

初学vue3与ts:element-plus的警告(Extraneous non-props attributes (ref_key) ...)

用了vue3与ts&#xff0c;ui我就选了element-plus element-plus官网&#xff1a;https://element-plus.org/zh-CN/ element-plus官网(国内镜像站点)&#xff1a;https://element-plus.gitee.io/zh-CN/ 国内镜像站点如果进不去的话&#xff0c;在element-plus官网最下面的链接-&…

「Verilog学习笔记」任意小数分频

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule div_M_N(input wire clk_in,input wire rst,output wire clk_out );parameter M_N 8d87; parameter c89 8d24; // 8/9时钟切换点parameter di…

Windows测试端口连通性(Telnet勾选)

“win““r”之后&#xff0c;telnet地址端口号 在最新版本的Windows中&#xff0c;默认情况下并没有安装Telnet客户端。如果遇到"telnet不是内部或外部命令…"的错误&#xff0c;请手动安装Telnet客户端。你可以在控制面板的"程序和功能"选项卡中找到&quo…

spring boot mybatis TypeHandler 源码如何初始化及调用

目录 概述使用TypeHandler使用方式在 select | update | insert 中加入 配置文件中指定 源码分析配置文件指定Mapper 执行query如何转换 结束 概述 阅读此文 可以达到 spring boot mybatis TypeHandler 源码如何初始化及如何调用的。 spring boot 版本为 2.7.17&#xff0c;my…

学生档案管理系统设计

摘要 随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。作为计算机应用的一部分,使用计算机对学生档案信息进行管理,具有着手工管理所无法比拟的优点.例如:检索迅速、查找方便、可靠性高、存储量…

python-学生管理|汉罗塔

1.编写程序&#xff0c;实现学生信息管理系统。 运行程序&#xff0c;在控制台输入“1”之后的结果如下所示&#xff1a; 学生管理系统 1.添加学生信息 2.删除学生信息 3.修改学生信息 4.显示所有学生信息 0.退出系统 请选择功能&#xff1a;1 请输入新学生的姓名:小红 请输入…

如何解决vue中的组件样式冲突

目录 1&#xff1a;组件样式冲突问题 2&#xff1a;导致组件之间样式冲突的根本原因是&#xff1a; 3&#xff1a;问题演示 4&#xff1a;通过设置scoped解决组件之间样式冲突问题 5&#xff1a;设置scoped解决组件样式冲突的原理 6&#xff1a;使用deep修改子组件的样式…

AT COMMAND(转载)

AT&#xff08;Attention&#xff09;指令是由 Dennis Hayes 发明的&#xff0c;所以也称为 Hayes command set。AT 指令最初是用来指导 modem 工作的&#xff0c;后面随着技术的发展&#xff0c;低速 modem 已经退出了市场&#xff0c;但 AT 指令却不断发展&#xff0c;并且在…

多线程中死锁是如何产生的?如何检测?如何避免?

一、死锁是如何产生的&#xff1f; 死锁&#xff1a;是指两个或多个线程在执行过程中&#xff0c;因争夺资源而造成的一种僵局。具体来说&#xff0c;每个线程持有一部分资源&#xff0c;并等待其他线程所持有的资源释放&#xff0c;导致所有线程都无法继续执行。 例如&#…

马斯克“赛博皮卡”Cybertruck交付!43万起售,性能强如猛兽

原创 | 文 BFT机器人 埃隆马斯克常常被称为是“天才与疯子”的结合&#xff0c;一直是一个争议不断的人物。他九十年代创办电子支付公司&#xff1b;2004年成立特斯拉&#xff0c;开创了一个汽车领域的新时代&#xff1b;人到中年又扬言要发射卫星建立全球无线网…… 许多科技…

Python必备神器揭秘:15个最热门库全解析

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python生态系统中拥有大量优秀的库&#xff0c;为开发者提供了广泛且强大的工具。本文将介绍15个最受欢迎的Python库&#xff0c;包括它们的功能、优点以及示例代码&#xff0c;帮助读者更全面地了解和使用这些库…

游戏开发常见算法

1.根据权重获取不同的值&#xff1a; 算法思想&#xff1a; 代码实现&#xff1a; _proto.randWeightEnemy function (enemyIdMap, enemyIds, targetWeight, weightArray, monsterNumLimit) {console.log("目标权重值"targetWeight); //targetWeight的值为1700var r…

基于SpringBoot实现的电影院售票系统

一、 系统架构 前端&#xff1a;html | jquery | bootstrap 后端&#xff1a;springboot | thymeleaf | spring-data-jpa 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 首页 02. 登录页 03. 管理端-电影列表 04. 管理端-添加电影 05. 管…

[PyTorch][chapter 4][李宏毅深度学习][Gradient Descent]

前言&#xff1a; 目录: 1: 梯度下降原理 2: 常见问题 3&#xff1a; 梯度更新方案 4&#xff1a; 梯度下降限制 一 梯度下降原理 机器学习的目标找到最优的参数,使得Loss 最小 为什么顺着梯度方向loss 就能下降了。主要原理是泰勒公式。 假设损失函数为 忽略二阶导数, 当 …

【Python】创建简单的Python微服务Demo与FastAPI

创建简单的Python微服务Demo与FastAPI 在微服务架构中&#xff0c;通过FastAPI框架创建一个简单的Python微服务Demo涉及多个步骤&#xff0c;包括定义服务、使用框架、进行通信等。在这篇文章中&#xff0c;我们将使用FastAPI框架创建两个简单的微服务&#xff0c;它们通过RES…

k8s部署单机模式的minio

k8s部署单机模式的minio 一、说明二、yaml内容三、步骤3.1 创建资源3.2 查看启动日志3.2 查看svc并访问控制台 一、说明 项目使用minio&#xff0c;准备在k8s环境部署一套minio试用。 1.关于minio的原理和概念参考: https://mp.weixin.qq.com/s?__bizMzI3MDM5NjgwNg&mid…

zabbix6.4监控交换机发现ICMP报错Ping item must have target or host interface specified

报错信息&#xff1a; 查看监控项&#xff1a; 修改键值&#xff1a; 保存再次检查&#xff0c;发现又报错/usr/sbin/fping: [2] No such file or directory 原因是&#xff0c;zabbix-server上没有安装fping工具 解决方法&#xff1a;yum install fping -y 之后数据采集正常…

Retrofit的转换器

一、前言 1.为什么要使用Retrofit转换器 在我们接受到服务器的响应后&#xff0c;目前无论是OkHttp还是Retrofit都只能接收到String字符串类型的数据&#xff0c;在实际开发中&#xff0c;我们经常需要对字符串进行解析将其转变为一个JavaBean对象&#xff0c;比如服务器响应…