使用enum关键字定义的枚举类实现接口
首先我们要知道,这里我们说的使用enum关键字定义的枚举类实现接口中的接口都是内部声明了抽象方法的接口
我们使用enum关键字定义的枚举类实现接口有两种情况:
情况一:
实现接口,在枚举类中统一实现接口中的抽象方法
- 对于情况一而言,接口中的方法时在类中统一实现的,那么这个时候所有的枚举类对象如果执行这个接口中的方法时都是执行的这一个统一的方法
情况二:
实现接口,让枚举类的每个对象分别实现接口中的抽象方法
- 对于情况二而言, 接口中的方法是让每个对象都分别实现了的,没有去统一的实现接口中的抽象方法,那么这个时候使用哪个对象调用的接口中的抽象方法,那么就会调用的哪个对象具体重写的方法
注意: 情况二方式只适用于通过enum关键字定义的枚举类,如果是自定义枚举类的方式则不适用
这里我们通过举例来理解情况一和情况二的区别
1. 首先是情况一
- 我们先给出接口
package 枚举类.枚举类的定义.enum关键字定义枚举类;
public interface Info {
//省略了public abstract
void show();
}
- 然后我们给出使用情况一方式实现了接口的枚举类
package 枚举类.枚举类的定义.enum关键字定义枚举类;
//通过enum关键字定义枚举类
public enum Season2 implements Info{
/*
1. 通过enum关键字定义枚举类时,首先我们上来就要提供当前枚举类的对象, 多个对象之间使用,(逗号)隔开,末尾对象使用;(封号结束)
注意: 这里创建对象的时候省略了很多不重要的东西比如: new关键字, 变量类型 ,构造方法名
补充: 这里如果是使用无参构造器创建对象的话那么()也可以省略
*/
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","冰天雪地");
/*
后面的步骤就和我们自定义枚举类时一样
*/
/*
2. 声明Season1类的属性(常量), 使用private final关键字共同修饰
*/
private final String seasonName;
private final String seasonDesc;
/*
3. 私有化类的构造器,并给对象的属性赋值
注意: 使用构造器赋值的方式可以让我们的每个对象都唯一存在一个常量
*/
private Season2(String seasonName , String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
/*
4. 其他诉求:
4.1 获取枚举类对象的属性
*/
public String getSeasonName(){
return this.seasonName;
}
public String getSeasonDesc(){
return this.seasonDesc;
}
/*
4.2 根据需求提供toString()方法
注意: 这里我们即使不重写toString()方法,输出此枚举类对象的时候也不会输出地址值,因为我们使用enum关键字定义的枚举类都是直接继承了
java.lang.Enum类,而Enum类中重写了继承自Object类的toString()方法,Enum类中重写的toString()方法输出的就是枚举类对象所对应的常量名
*/
@Override
public String toString() {
return "Season1{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
//重写的接口中的show()方法
@Override
public void show(){
System.out.println("这是一个季节!");
}
}
//对使用enum关键字定义的枚举类的测试
class Season2Test{
public static void main(String[] args) {
//获取枚举类的对象
Season2 spring = Season2.SPRING;
//调用show()方法,这个时候不管我们使用哪个枚举类的对象调用此方法,都会输出: 这是一个季节!
spring.show();
}
}
2. 然后是情况二
- 我们同样还是先给出接口
- 两次的接口都是同一个接口
package 枚举类.枚举类的定义.enum关键字定义枚举类;
public interface Info {
//省略了public abstract
void show();
}
- 然后我们给出使用情况二方式实现此接口的枚举类
package 枚举类.枚举类的定义.enum关键字定义枚举类;
//通过enum关键字定义枚举类
public enum Season3 implements Info{
/*
1. 通过enum关键字定义枚举类时,首先我们上来就要提供当前枚举类的对象, 多个对象之间使用,(逗号)隔开,末尾对象使用;(封号结束)
注意: 这里创建对象的时候省略了很多不重要的东西比如: new关键字, 变量类型 ,构造方法名
补充: 这里如果是使用无参构造器创建对象的话那么()也可以省略
*/
//注意,这里我们给每个对象都重写了接口中的抽象方法
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. 声明Season1类的属性(常量), 使用private final关键字共同修饰
*/
private final String seasonName;
private final String seasonDesc;
/*
3. 私有化类的构造器,并给对象的属性赋值
注意: 使用构造器赋值的方式可以让我们的每个对象都唯一存在一个常量
*/
private Season3(String seasonName , String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
/*
4. 其他诉求:
4.1 获取枚举类对象的属性
*/
public String getSeasonName(){
return this.seasonName;
}
public String getSeasonDesc(){
return this.seasonDesc;
}
/*
4.2 根据需求提供toString()方法
注意: 这里我们即使不重写toString()方法,输出此枚举类对象的时候也不会输出地址值,因为我们使用enum关键字定义的枚举类都是直接继承了
java.lang.Enum类,而Enum类中重写了继承自Object类的toString()方法,Enum类中重写的toString()方法输出的就是枚举类对象所对应的常量名
*/
@Override
public String toString() {
return "Season1{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
//对使用enum关键字定义的枚举类的测试
class Season3Test{
public static void main(String[] args) {
//获取枚举类的对象
Season3 spring = Season3.SPRING;
//调用show()方法,这个时候使用不同的对象调用show()方法都会有不同的结果,因为每个对象中都分别重写了接口中的抽象方法
spring.show();
}
}
总结:
1.只有枚举类在实现接口之后可以通过给每个对象重写接口中的抽象方法而不用去统一在枚举类中实现
- 那么为什么枚举类可以,其他类不可以?
- 因为接口中定义的必须要被重写的方法一定义非静态方法,那么非静态方法的调用者又是对象,那么如果是普通的类,那么可以无限的创建对象,我们不可能让无限个对象都去重写接口中的方法,我们就只能在类中统一进行重写,所有这个普通的类的对象都使用这个重写的方法 - 但是枚举类不同,枚举类的对象时给定的(枚举类的对象数量是确定的, 每个对象也都是确定的,不可变的),所以我们可以让有限个枚举类的对象分别去实现接口中的抽象方法