枚举
需求创建季节Seanson
对象,请设计并完成。Enumeration01.java
由于对象季节对象有如下特点:
- 季节的值是有限的几个值【
spring summer autumn winter
】 - 只读,不需要修改
package JAVA面向对象高级部分.enumer_;
/**
* @author: 海康
* @version: 1.0
*/
public class Enumeration01 {
public static void main(String[] args) {
Season spring = new Season("spring", "温暖");
Season summer = new Season("summer", "炎热");
Season autumn = new Season("autumn", "凉的");
Season winter = new Season("winter", "寒冷");
/**
* 由于对于季节而已,他的对象(具体值)是固定的四个,不会更多了
* 这样的设计类的思路,不能体现季节的固定四个对象
* 因此,这样引出了枚举来解决【枚举类:一个一个的例举】
*/
}
}
/**
* 枚举的引出:需求创建季节对象,并完成
*/
class Season {
private String name;
private String desc;//描述
public Season() {
}
public Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
解决方案-枚举
由于上述的季节对象,存在于属性可以被修改,所以引入了枚举可以解决
枚举是一组常量的集合,可以这里理解:枚举属于一种特殊的类,里面包含一组有限的特定的对象
枚举的二种实现方式
- 自定义类实现枚举
- 使用
enum
关键字实现枚举
自定义枚举:
- 1.将构造器进行私有化,防止直接其他类
new
- 2.在本类中提供静态
+final
修饰的对象或属性 - 3.对外提供
getXX
方法
自定义类实现枚举-应用案例
- 不需要提供
setXXX
方法,因为枚举对象值通常为只读 - 对枚举对象,属性使用
final+static共同修饰
,实现底层优化,不用加载类信息可以直接访问 - 枚举对象名通常使用全部大写,常量的命名规范
- 枚举对象根据需要,也可以有多个属性值
package JAVA面向对象高级部分.enumer_;
/**
* @author: 海康
* @version: 1.0
*/
public class Enumeration02 {
public static void main(String[] args) {
}
}
/**
* 自定义枚举三步:
* 1.将构造器进行私有化,防止直接其他类new
* 2.在本类中提供静态+final修饰的对象或属性
* 3.对外提供getXX方法
*/
class Season {//季节类
private String name;
private String description;//季节描述
public static final Season SPRING = new Season("spring", "温暖");
public static final Season SUMMER = new Season("summer", "炎热");
public static final Season AUTUMN = new Season("autumn", "凉的");
public static final Season WINTER = new Season("winter", "寒冷");
private Season(){}
private Season(String name,String description){
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
}
自定义类实现枚举-小结
小结:进行自定义类实现枚举,有如下特点:
- 构造器私有化
- 本类内部创建一组对象
- 对外暴露对象【通过为对象添加public final static修饰】
- 可以提供get方法,但是不要提供set方法
enum
关键字实现枚举–快递入门
基本介绍:使用enum
来实现前面的枚举案例,体会和自定义的实现枚举的不同的地方。
使用enum
自定义枚举的步骤:
- 使用关键字
enum
替代class
public static final Season SPRING = new Season("spring","温暖");
直接使用SPRING("spring","温暖");
解读【常量名(实参列表);
】- 如果有多个常量(对象),使用
,
号间隔即可 - 如果使用
enum
来实现枚举,要求将定义常量对象,写在前面 - 如果我们使用的是无参构造器,创建常量对象,则可以省略
()
package JAVA面向对象高级部分.enumer_;
/**
* @author: 海康
* @version: 1.0
*/
public class Enumeration03 {
public static void main(String[] args) {
System.out.println(Season02.SUMMER);
}
}
/**
* enum关键字实现枚举--快速入门
* 说明:
* 使用enum来实现前面的枚举案例,看老师演示,主要体会和自定义类实现枚举不同地方
*/
enum Season02 {
/**
* 使用enum关键字自定义枚举的注意事项:
* 1.使用关键字enum 替代 class
* 2.public static final Sanson SPRING = new SanSon("spring","温暖");
* 3.如果有多个常量(对象),使用","号分隔即可
* 4.如果使用enum来实现枚举,要求将定义常量对象,写在最前面,否则报错
*/
SPRING ("spring", "温暖"), SUMMER ("summer", "炎热"),
AUTUMN ("autumn", "凉的"), WINTER ("winter", "寒冷");
private String name;
private String description;//描述
private Season02(){}
private Season02(String name,String description){
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return "Season02{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
}
enum
关键字实现枚举注意事项(必须记住)
- 当我们使用
enum
关键字开发一个枚举类时,默认会继承Enum
类,而且是一个final
类【需要使用javap
工具来获取】 - 传统
public static final Season2 SPRING = new Season2("spring","温暖");
,简化成SPRING("spring","温暖");
,这里必须知道,它调用的是哪个构造器【构造这句话是相当于创建对象,并调用相关的构造器完成属性的初始化】 - 如果使用无参构造器 创建 枚举对象 ,则实参列表和小括号都可以省略
- 当有多个枚举对象时,使用
","
间隔,最后一个分号结尾 - 枚举对象必须放在枚举的行首
练习题目:
下面代码是否正确,并说明表示含义?
enum Gender{
BOY,GIRL;
}
1.上述的代码是正确的
2.有一个枚举类Gender,没有属性
3.有两个枚举对象 BOY,GIRL,使用的无参构造器创建
enum
常用方法说明
基本介绍:使用关键字enum
时,会隐式继承Enum
类,这样我们就可以使用Enum
类相关的方法。
public abstract class Enum<E extends Enum<E>> implements Comparable<E>,Serializable{}
enum
类的属性和方法
enum
属性和方法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
private final String name;
private final int ordinal;//比较,顺序
protected Enum(String name, int ordinal) {//了解
this.name = name;
this.ordinal = ordinal;
}
public final int compareTo(E o) {//重点
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;//返回当前枚举对象和比较枚举对象的序号的差
}
public final String name() {//重点
return name;//返回枚举对象的名字
}
//通过底层源码发现:name和toString方法的作用是一样的
public String toString() {//重点
return name;//返回枚举对象的名字
}
public final int ordinal() {//重点
return ordinal;//返回枚举对象的序号,默认是从0开始
}
public final boolean equals(Object other) {//重点
return this==other;
}
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {//重点
//返回你传入的枚举对象的名称,获取该枚举对象,如果传入名称不存在,则报错
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
源码隐藏的方法(重点):
vaules():用于返回当前枚举集合的所有枚举对象
public final int hashCode() {了解
return super.hashCode();
}
enum
常用方法的演示代码
package JAVA面向对象高级部分.enumer_.enumMethod;
/**
* @author: 海康
* @version: 1.0
* 演示Enum常用的方法
*/
public class EnumMethod {
public static void main(String[] args) {
//toString:Enum类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息
Sanson spring = Sanson.SPRING;
System.out.println(spring.toString());//Enum类重写了toString方法,用于返回枚举对象的名称
//name:返回当前对象名(常量名),子类中不能重写
Sanson autumn = Sanson.AUTUMN;
System.out.println(autumn.name());//name方法用于返加枚举对象的名称
//ordinal:返回当前对象的位置,默认从0开始
Sanson winter = Sanson.WINTER;
System.out.println(winter.ordinal());//ordinal方法用于返回当前对象的序号,默认是0开始
//values: 返回当前枚举类中所有的常量
Sanson[] values = Sanson.values();
for (Sanson sanson:
values) {
System.out.println(sanson);
}
//valueOf : 将字符串转换成枚举对象,要求字符串必须存在在枚举中【也就是枚举对象名】,否则报错
Sanson spring1 = Sanson.valueOf("SPRING");
System.out.println(spring1);//默认调用toString
System.out.println(spring == spring1);//返回true,说明获取都是一个枚举对象
//compareTo: 比较两个枚举常量【就是比较枚举对象的序号】,比较是编号
Sanson summer = Sanson.SUMMER;
//返回当前枚举对象的序号和传入枚举对象的序号差,用当前枚举对象减去传入的枚举对象
int i = summer.compareTo(spring1);
System.out.println(i);
}
}
enum Sanson {
/**
* 枚举对象会根据类型自动匹配构造器
*/
SPRING ("spring", "温暖"), SUMMER("summer", "炎热"),
AUTUMN ("autumn", "凉的"), WINTER("winter", "寒冷");
private String name;
private String desc;//描述
private Sanson(String name, String desc) {//将构造器进行私有化防止直接new本类对象
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Sanson{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
练习题目:
package JAVA面向对象高级部分.enumer_;
/**
* @author: 海康
* @version: 1.0
*/
public class EnumExercise {
public static void main(String[] args) {
Week[] values = Week.values();
for (Week weeks:
values) {
System.out.println(weeks.getDest());
}
}
}
enum Week {
MONDAY("星期一"),TUESDAY("星期二"),
WEDNESDAY("星期三"),THURSDAY("星期四"),
FRIDAY("星期五"),SATURDAY("星期六"),
SUNDAY("星期日");
private String dest;
Week(String dest) {
this.dest = dest;
}
public String getDest() {
return dest;
}
@Override
public String toString() {
return "Week{" +
"dest='" + dest + '\'' +
'}';
}
}
enum
实现接口
1.使用enum
关键字后,就不能再继承其它类了,因为enum
会隐式继承Enum
,而java
是单继承机制
2.枚举类和普通类一样,可以实现接口,如下形式。
enum 类名 implements 接口1,接口2{}