Java 面向对象 - 枚举类详解
最编程
2024-03-29 20:41:40
...
1.什么是枚举类
枚举类就是 对象个数有限且确定的类。
比如:季节类,一共就四个对象 : 春,夏,秋,冬。
* 对象个数有限,可以一一列举出来;
* 对象一旦被定义,不可进行修改。
【当需要定义一组常量时,强力推荐使用枚举类】
2.自定义实现枚举类
根据枚举类的定义,自定义实现枚举类时需要完成的要求:
1.对象属性 用 private final修饰
2.构造器私有化,private 修饰
3.对象在类中创建完成,public static final 修饰
4.可以存在其他的方法,如 对象属性的getter方法,toString方法等
下面定义了一个枚举类:存在四个季节对象的Season类
public class Season {
//1.私有化属性
private final String seasonName;
private final String seasonDesc;
//2.私有化构造器
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//3.声明四个对象 春夏秋冬
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("冬天","白雪皑皑");
//4.其他方法1: 对象属性的getter方法,此时无setter方法的
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//4.其他方法2: toString()方法
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
测试使用枚举类
public class Application {
public static void main(String[] args) {
// 正常使用自定义的枚举类
Season spring = Season.SPRING;
System.out.println(spring); // 默认调用toString方法
System.out.println(spring.getSeasonName()); // 正常调用方法
System.out.println("=========================");
}
}
执行结果如下:
Season{seasonName='春天', seasonDesc='春暖花开'}
春天
=========================
3.使用enum关键字定义枚举类
定义的格式要求 :
1.使用enum关键字代替class;
2.类的枚举对象必须在类的最开始定义;
3.有多个对象时,对象之间用英文的逗号隔开,在最后一个对象的后面用英文分号结束;
4.声明枚举对象时的格式为
【枚举对象名称1,枚举名称2.。。。】 或
【枚举对象名称1(构造方法参数。。。),枚举名称2(构造方法参数)。。。】
5.属性仍然用 private final 进行修饰;
6.构造方法仍然用 private 修饰;
7.可以写其他的方法:getter、重写toString()等
下面是一个使用enum关键字定义的枚举类
public enum Week {
// 枚举对象
MONDAY ("星期一","上一天的语文课"),
TUESDAY ("星期二","上一天的数学课"),
WEDNESDAY ("星期三","上一天的英语课"),
THURSDAY ("星期四","上一天的物理课"),
FRIDAY ("星期五","上一天的化学课"),
SATURDAY ("星期六","上一天的生物课"),
SUNDAY ("星期日","上一天的自习课");
//声明属性
private final String weekName;
private final String weekDesc;
//构造方法
Week(String weekName, String weekDesc) {
this.weekName = weekName;
this.weekDesc = weekDesc;
}
// 其他方法:getter方法,toString()方法等
public String getWeekName() {
return weekName;
}
public String getWeekDesc() {
return weekDesc;
}
@Override
public String toString() {
return "Week{" +
"weekName='" + weekName + '\'' +
", weekDesc='" + weekDesc + '\'' +
'}';
}
}
测试使用枚举类
public class Application {
public static void main(String[] args) {
// 正常使用枚举类
System.out.println(Week.SUNDAY);
System.out.println(Week.SUNDAY.getWeekName());
System.out.println(Week.SUNDAY.getWeekDesc());
System.out.println("=========================");
}
}
执行结果如下:
Week{weekName='星期日', weekDesc='上一天的自习课'}
星期日
上一天的自习课
=========================
4.一个简化版的枚举类
枚举类中可以没有任何的属性,直接声明各个枚举对象。
具体形式如下:
/**
* 直接放上枚举对象的枚举类,
* 十分的简洁明了。
*/
public enum WeekSimple {
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUM;
}
5.enum枚举类的父类Enum类的常用方法
1.使用enum定义的枚举类的直接父类是 : java.lang.Enum;
2.直接继承的父类的常用方法如下:
values():返回枚举类中的枚举对象的数组,可以方便进行遍历;
valueOf(String objName):返回枚举类中 与参数objName 名称一致的枚举对象,
【注意:参数必须是枚举对象中的其中一个,否则程序会抛出异常】;
toString() : 直接返回枚举对象的名称;
ordinal():返回枚举对象在声明时的顺序,且顺序从0开始。
name():直接返回枚举对象的名称,推荐使用toString()!
方法测试:以第四小结中的简单的枚举类为例
public class Application {
public static void main(String[] args) {
// 枚举类的常用方法
WeekSimple[] values = WeekSimple.values();
System.out.println(Arrays.toString(values));
WeekSimple aa = WeekSimple.valueOf("MONDAY");
System.out.println(aa);
System.out.println(WeekSimple.MONDAY.toString());
System.out.println(WeekSimple.MONDAY.ordinal());
System.out.println(WeekSimple.THURSDAY.name());
}
}
执行结果
[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUM]
MONDAY
MONDAY
0
THURSDAY
6.实现接口的枚举类
枚举类也是可以实现接口的,实现方式有两种,分别如下:
6.1 方式一:全局实现
全局实现:就是在枚举类中直接实现,此时所有的枚举对象都拥有相同的方法实现
public enum SeasonWithInterface implements AA {
Spring,SUMMER,AUTUMN,WINTER;
/**
* 全局实现接口的方法
*/
@Override
public void sayHello() {
System.out.println("Hello EveryOne!");
}
}
// 定义一个接口
interface AA{
void sayHello();
}
6.2 方式二:对象实现
对象实现:就是在声明对象的时候实现,此时每个对象都单独对接口中的方法进行实现
public enum SeasonWithInterface implements AA {
SPRING(){
@Override
public void sayHello() {
System.out.println("Hello Spring");
}
},
SUMMER(){
@Override
public void sayHello() {
System.out.println("Hello SUMMER");
}
},
AUTUMN(){
@Override
public void sayHello() {
System.out.println("Hello AUTUMN");
}
},
WINTER(){
@Override
public void sayHello() {
System.out.println("Hello WINTER");
}
};
}
// 定义一个接口
interface AA{
void sayHello();
}
7.完成
Congratulations!
You are one step closer to sucess!
上一篇: 人工神经网络--初寒
下一篇: 带你玩转邮差的收藏 - II.创建收藏集
推荐阅读
-
猫和老鼠 - Java 面向对象的特征排序
-
35 岁实现财务*,腾讯程序员手握2300万提前退休?-1000万房产、1000万腾讯股票、加上300万的现金,一共2300万的财产。有网友算了一笔账,假设1000万的房产用于自住,剩下1300万资产按照平均税后20-50万不等进行计算,大约花上26-60年左右的时间才能赚到这笔钱。也就是说,普通人可能奋斗一辈子,才能赚到这笔钱。在很多人还在为中年危机而惶惶不可终日的时候,有的人的35岁,就已经安全着陆,试问哪个打工人不羡慕?但问题是有这样财富积累必然有像样的实力做靠山。没有人可以不劳而获。 看到这里,肯定有人说,那么对于普通人来说,卷可能真就成了唯一的出路。但是卷也有轻松的卷,“偷懒”的卷法,对于程序员而言,刨除掉一时无法改掉的开会传统占用的大部分时间,如何把有限的时间和精力放在真正重要的架构设计、需求设计上,而不是重复的造*,编码、改bug、手动测试。因此在科技改变生活的今天,学会使用AI工具成为程序员们的必备技能。 以全栈式全自动的软件开发工具飞算SoFlu软件机器人为例,作为全球首款面向微服务架构设计和最佳实践的软件机器人,SoFlu软件机器人改变了原来手工编码的作业模式,通过可视化拖拽方式以及参数配置就能实现等同于编写复杂代码的业务逻辑,在设计业务逻辑时就完成了微服务应用开发,做到“业务即图,图即代码”,实现“软件开发,十倍提效”。 而作为飞算SoFlu软件机器人的一个重要组成部分,FuncGPT(慧函数)支持所有类型函数创建。通过自然语言描述Java函数需求,实时生成高质量、高可读性的Java函数代码。生成代码可直接复制到IDEA,或一键导入Java全自动开发工具函数库。 FuncGPT(慧函数)具有五大核心能力: ● 自然语言:通过自然语言即可生成函数,降低软件开发门槛。 ● 秒级函数开发:全自动秒级开发函数,秒级完成,效率千倍提升。 ● 一站式函数开发应用:函数生成即可直接应用,效率、安全有保障。 ● 质量可靠:生成的函数代码符合业界规范、具备良好的可读性,符合最优解。 ● 灵活生成:可以根据开发人员的具体需求生成并支持调整和修改。 以“将文件流转换为File对象”这个需求为例,以下是FuncGPT(慧函数)秒级生成的代码: / 类名:FileConverter // 函数名:convertStreamToFile // 函数功能:将文件流转换为File对象 // POM依赖包:无 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileConverter { /** * 将文件流转换为File对象 * @param inputStream 文件流 * @param filePath 文件路径 * @param fileName 文件名 * @return 转换后的File对象 * @throws IOException 如果发生I/O异常 */ public static File convertStreamToFile(InputStream inputStream, String filePath, String fileName) throws IOException { File file = new File(filePath + File.separator + fileName); // 创建File对象 try (FileOutputStream outputStream = new FileOutputStream(file)) { // 创建文件输出流 byte buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { // 从文件流读取数据并写入文件 outputStream.write(buffer, 0, bytesRead); } } return file; // 返回转换后的File对象 } } // 函数示例 // 将文件流转换为File对象示例 // 入参:inputStream,文件流 // 入参:filePath,文件路径 // 入参:fileName,文件名 // 出参:file,转换后的File对象 // 调用示例: // InputStream inputStream = new FileInputStream("example.txt"); // String filePath = "C:\\Users\\User\\Documents"; // String fileName = "example.txt"; // File file = FileConverter.convertStreamToFile(inputStream, filePath, fileName); // System.out.println(file.getAbsolutePath); // 输出结果:例如,将文件流转换为File对象后,文件的绝对路径为:C:\Users\User\Documents\example.txt // 则输出结果为:C:\Users\User\Documents\example.txt 通过分析,不难发现以上代码:
-
JAVA 系列初学者参考类和对象 (2)
-
一种结构设计模式,允许在对象中动态添加新行为。它通过创建一个封装器来实现这一目的,即把对象放入一个装饰器类中,然后把这个装饰器类放入另一个装饰器类中,以此类推,形成一个封装器链。这样,我们就可以在不改变原始对象的情况下动态添加新行为或修改原始行为。 在 Java 中,实现装饰器设计模式的步骤如下: 定义一个接口或抽象类作为被装饰对象的基类。 公共接口 Component { void operation; } } 在本例中,我们定义了一个名为 Component 的接口,该接口包含一个名为 operation 的抽象方法,该方法定义了被装饰对象的基本行为。 定义一个实现基类方法的具体装饰对象。 公共类 ConcreteComponent 实现 Component { public class ConcreteComponent implements Component { @Override public void operation { System.out.println("ConcreteComponent is doing something...") ; } } 定义一个抽象装饰器类,该类继承于基类,并将装饰对象作为一个属性。 公共抽象类装饰器实现组件 { protected Component 组件 public Decorator(Component component) { this.component = component; } } @Override public void operation { component.operation; } } } 在这个示例中,我们定义了一个名为 Decorator 的抽象类,它继承了 Component 接口,并将被装饰对象作为一个属性。在操作方法中,我们调用了被装饰对象上的同名方法。 定义一个具体的装饰器类,继承自抽象装饰器类并实现增强逻辑。 公共类 ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component 组件) { super(component); } } public void operation { super.operation System.out.println("ConcreteDecoratorA 正在添加新行为......") ; } } 在本例中,我们定义了一个名为 ConcreteDecoratorA 的具体装饰器类,它继承自装饰器抽象类,并实现了操作方法的增强逻辑。在操作方法中,我们首先调用被装饰对象上的同名方法,然后添加新行为。 使用装饰器增强被装饰对象。 公共类 Main { public static void main(String args) { Component 组件 = new ConcreteComponent; component = new ConcreteDecoratorA(component); 组件操作 } } 在这个示例中,我们首先创建了一个被装饰对象 ConcreteComponent,然后通过 ConcreteDecoratorA 类创建了一个装饰器,并将被装饰对象作为参数传递。最后,调用装饰器的操作方法,实现对被装饰对象的增强。 使用场景 在 Java 中,装饰器模式被广泛使用,尤其是在 I/O 中。Java 中的 I/O 库使用装饰器模式实现了不同数据流之间的转换和增强。 让我们打开文件 a.txt,从中读取数据。InputStream 是一个抽象类,FileInputStream 是专门用于读取文件流的子类。BufferedInputStream 是一个支持缓存的数据读取类,可以提高数据读取的效率,具体代码如下: @Test public void testIO throws Exception { InputStream inputStream = new FileInputStream("C:/bbb/a.txt"); // 实现包装 inputStream = new BufferedInputStream(inputStream); byte bytes = new byte[1024]; int len; while((len = inputStream.read(bytes)) != -1){ System.out.println(new String(bytes, 0, len)); } } } } 其中 BufferedInputStream 对读取数据进行了增强。 这样看来,装饰器设计模式和代理模式似乎有点相似,接下来让我们讨论一下它们之间的区别。 第三,与代理模式的区别: 代理模式的目的是控制对对象的访问,它在对象外部提供一个代理对象来控制对原对象的访问。代理对象和原始对象通常实现相同的接口或继承相同的类,以确保两者可以相互替换。 装饰器模式的目的是动态增强对象的功能,而这是通过对象内部的包装器来实现的。在装饰器模式中,装饰器类和被装饰对象通常实现相同的接口或继承自相同的类,以确保两者可以相互替代。装饰器模式也被称为封装器模式。 在代理模式中,代理类附加了与原类无关的功能。
-
如何在 Java 地图中转实体类对象 [与工具类相关的方法
-
1.7 Java 面向对象 [类、对象、方法、面向过程与面向对象的区别
-
Java 枚举类型的介绍和使用 - 2. 枚举类的使用
-
Java 类内部定义枚举类 java 内部枚举
-
java 枚举枚举类的用法和高级使用方法
-
java 的枚举类枚举