P425~P442
要求创建季节对象,设计并完成,com.enumeration.Enumeration01.java
public class Enumeration01 {
public static void main(String[] args) {
//因为对于季节而说,他的对象(具体值)是固定的,不会有更多
Season spring = new Season("春天", "温暖");
Season winter = new Season("冬天", "寒冷");
Season summer = new Season("夏天", "炎热");
Season autumn = new Season("秋天", "凉爽");
}
}
class Season {
private String name;
private String desc;//描述
public Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
}
枚举类实现方式
- 自定义类实现枚举
- 使用enum关键字实现枚举
自定义类实现枚举,com.enumeration.Enumeration02.java
- 不需要提供set方法,因为枚举对象值通常为只读
- 对枚举对象/属性使用final+static共同修饰,实现底层优化
- 枚举对象名通常使用全部大写,常量的命名规范
- 枚举对象根据需要,也可以有多个属性
public class Enumeration02 {
public static void main(String[] args) {
//因为对于季节而说,他的对象(具体值)是固定的,不会有更多
System.out.println(Season02.AUTUMN);
}
}
//自定义枚举
class Season02{
private String name;
private String desc;//描述
//1、将构造器私有化,防止直接被new
//2、去掉set方法,防止属性被修改
//3、在内部创建固定的值
public static final Season02 SPRING = new Season02("春天", "温暖");
public static final Season02 WINTER = new Season02("冬天", "寒冷");
public static final Season02 SUMMER = new Season02("夏天", "炎热");
public static final Season02 AUTUMN = new Season02("秋天", "凉爽");
private Season02(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season02{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
自定义类实现枚举,特点:
- 构造器私有化
- 类内部创建一组对象
- 对外暴露对象,为对象添加public final static 修饰
- 可以提供get方法,但不提供set方法
enum关键字实现枚举,com.enumeration.Enumeration03.java
public class Enumeration03 {
public static void main(String[] args) {
System.out.println(Season03.AUTUMN);
}
}
//使用enum替代class
enum Season03 {
//public static final Season03 WINTER = new Season03("冬天", "寒冷");
//使用SPRING("春天","温暖")
//常量名(实参列表)
//如果有多个常量,使用逗号间隔
//要求常量对象写在最前面
SPRING("春天", "温暖"),
WINTER("冬天", "寒冷"),
SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽");
private String name;
private String desc;//描述
private Season03(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
enum注意事项
- 当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,并且变成final类
- public static final Season SPRING = new Season(“春天”,“温暖”),简化成SPRING(“春天”,“温暖”)
- 如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
- 当有多个枚举对象时,使用逗号间隔,最后一个分号结尾
- 枚举对象必须放在枚举类的首行
enum常用方法说明
使用关键字enum时,会隐式继承Enum类,这样我们就可以使用Enum类相关方法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>,SErializable{
}
常用方法
- toString:返回当前对象名,子类可以重写该方法,用于返回对象的属性信息
- name:返回当前对象名
- ordinal:返回当前对象的位置号,默认从0开始
- values:返回当前枚举类中所有的常量
- valueOf:将字符串转换成枚举对象,要求字符串必须为已有常量名
- compareTo:比较两个枚举常量,比较的是位置号
练习,com.enumeration.EnumerationExercise.java
- 声明Week枚举类,包含MONDAY,TUESDAY,WEDNEDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
- 使用values返回所有的枚举数组,并遍历输出
public class EnumerationExercise {
public static void main(String[] args) {
for(Week day:Week.values()){
System.out.println(day);
}
}
}
enum Week{
MONDAY("星期一"),
TUESDAY("星期二"),
WEDNEDAY("星期三"),
THURSDAY("星期四"),
FRIDAY("星期五"),
SATURDAY("星期六"),
SUNDAY("星期天");
private String name;
Week(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Enum实现接口
-
使用enum关键字后,就不能再继承其他类了,因为enum会隐式继承Enum,而java是单继承机制
-
枚举类和普通类一样,可以实现接口,如下
enum 类名 implements 接口1,接口2{}
注解
- 注解Annotation也被称为元数据Metadata,用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息
- 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息
- 在javaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等
- 在javaEE中,注解占据了更重要的角色,比如用来配置应用程序的任何切面,代替javaEE旧版中所遗留的繁冗代码和XML配置等
使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。
三个基本Annotation,com.anno.Annotation01.java
- @Override:限定某个方法,是重写父类方法,该注解只能用于方法
- @Deprecated:用于表示某个程序元素已过时
- @SuppressWarnings:抑制编译器警告
public class Annotation01 {
}
class Father {
public void fly() {
}
}
class Son extends Father {
@Override
//表示子类的fly是重写了父类的方法\
//如果写了@Override,编译器会检查该方法是否真的重写了父类的方法
// 如果的确重写了,则编译通过,如果没有构成重写,则编译错误
public void fly() {
super.fly();
}
}
Override
- @Override表示指定重写父类的方法,如果父类没有该方法,则会报错
- 如果不写@Override注解,而父类有该方法,仍然构成重写
- @Override只能修饰方法,不能修饰其他类、包、属性等
- 查看@Override注解源码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
1. @Target(ElementType.METHOD),说明只能修饰方法
2. @Target是修饰注解的注解,称为元注解
3. @interface,表示是一个注解类
Deprecated,com.anno.Deprecated_.java
public class Deprecated_ {
public static void main(String[] args) {
Dep a = new Dep();
a.hi();
}
}
@Deprecated
class Dep{
public int n1=10;
@Deprecated
public void hi(){
System.out.println("hi");
}
}
- @Deprecated修饰某个元素,表示该元素已经过时
- 可以使用被修饰的元素,但是不推荐使用该元素
- 可以修饰方法、类、字段、包、参数等等
- 可以用作版本升级过渡和兼容
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE,
METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
SuppressWarnings,com.anno.SuppressWarnings_.java
import java.util.ArrayList;
import java.util.List;
public class SuppressWarnings_ {
@SuppressWarnings({"all"})
public static void main(String[] args) {
// @SuppressWarnings 用来抑制警告信息
List list = new ArrayList();
list.add("jack");
list.add("tom");
list.add("mary");
int i;
System.out.println(list.get(1));
}
}
- @SuppressWarnings用来抑制警告信息
@SuppressWarnings({“all”})
- unchecked:忽略没有检查的警告
- rawtypes:忽略没有指定泛型的警告
- unused:忽略没有使用某个变量的警告
- @SuppressWarnings:可以修饰的程序元素为,查看@Target
@Target({TYPE, FIELD, METHOD, PARAMETER,
CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();//可以存放一个字符串数组,需要忽略的警告
}
元注解
元注解的种类
- Retention(保留),指定注解的作用范围,SOURCE、CLASS、RUNTIME
- Target,指定注解可以在哪些地方使用
- Documented,指定该注解是否会在javadoc体现
- Inherited,子类会继承父类注解
Retention
只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间,@Retention包含一个RetentionPolicy类型的成员变量,使用@Rentention时必须为该value成员变量指定值
Retention三种值
- @Retention(RetentionPolicy.SOURCE):编译器使用后,直接丢弃这种策略的注释
- @Retention(RetentionPolicy.CLASS):编译器将把注释记录在class文件中,当运行java程序时,JVM不会保留注释。这是默认值
- @Retention(RetentionPolicy.RUNTIME):编译器将把注释记录在class文件中,当运行java程序时,JVM会保留注释,程序可以通过反射获取该注释
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
Target
用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰哪些程序元素,@Target包含一个名为value的成员变量
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
Documented
用于指定被该元注解修饰的Annotation类将被javadoc工具提取成文档,即在生成文档时,可以看到该注释。
说明:定义为Documented的注释必须设置Retention值为RUNTIME
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
Inherited
被他修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注释
作业
com.homwork.Homework0901.java
- 在Frock类声明私有的静态属性currentNum[int类型],初始值为100000,作为衣服出场的序列号起始值
- 声明公有的静态方法getNextNum,作为生成上衣唯一序列号的方法,每调用一次,将currentNum增加100,并作为返回值
- 在TestFrock类的main方法中,分两次调用getNextNum方法,获取序列号并打印输出
- 在Frock类中声明serialNumber(序列号)属性,并提供对应的get方法
- 在Frock类的构造器中,通过调用getNextNum方法为Frock对象获取唯一序列号,赋给serialNumber属性
- 在TestFrock类的main方法中,分别创建三个Frock对象,并打印三个对象的序列号,验证是否为按100递增/
//1. 在Frock类声明私有的静态属性currentNum[int类型],初始值为100000,作为衣服出场的序列号起始值
//2. 声明公有的静态方法getNextNum,作为生成上衣唯一序列号的方法,每调用一次,将currentNum增加100,
// 并作为返回值
//3. 在TestFrock类的main方法中,分两次调用getNextNum方法,获取序列号并打印输出
//4. 在Frock类中声明serialNumber(序列号)属性,并提供对应的get方法
//5. 在Frock类的构造器中,通过调用getNextNum方法为Frock对象获取唯一序列号,赋给serialNumber属性
//6. 在TestFrock类的main方法中,分别创建三个Frock对象,并打印三个对象的序列号,验证是否为按100递增
public class Homework0901 {
public static void main(String[] args) {
System.out.println(Frock.getNextNum());
System.out.println(Frock.getNextNum());
System.out.println(new Frock().getSerialNumber());
System.out.println(new Frock().getSerialNumber());
System.out.println(new Frock().getSerialNumber());
}
}
class Frock {
private static int currentNum = 100000;
private int serialNumber;
public Frock() {
this.serialNumber = this.getNextNum();
}
public static int getNextNum() {
currentNum += 100;
return currentNum;
}
public int getSerialNumber() {
return serialNumber;
}
}
com.homwork.Homework0902.java
- 计算器接口具有work方法,功能是运算,有一个手机类Cellphone,定义方法testWork测试计算功能,调用计算接口的work方法
- 要求调用Cellphone对象的testWork方法,使用匿名内部类/
//1. 计算器接口具有work方法,功能是运算,有一个手机类CellPhone,
// 定义方法testWork测试计算功能,调用计算接口的work方法
//2. 要求调用CellPhone对象的testWork方法,使用匿名内部类/
public class Homework0902 {
public static void main(String[] args) {
new CellPhone().testWork(new Caculate() {
@Override
public void work(double n1,double n2) {
System.out.println(n1+n2);
}
},1,2);
}
}
interface Caculate{
public void work(double n1,double n2);
}
class CellPhone{
public void testWork(Caculate caculate,double n1,double n2){
caculate.work(n1,n2);
}
}
com.homwork.Homework0903.java
- 创建一个Color枚举类
- 有RED,BLUE,BLACK,YELLOW,GREEN这个五个枚举值/对象;
- Color有三个属性redValue, greenValue, blueValue,
- 创建构造方法,参数包括这三个属性,
- 每个枚举值都要给这三个属性赋值,三个属性对应的值分别是
- red: 255,0,0 blue:0,0,255 black:0,0.,0 yellow:255,255,0 green:0,255,0
- 定义接口,里面有方法show,要求Color实现该接口
- show方法中显示三属性的值
- 将枚举对象在switch语句中匹配使用
//1. 创建一个Color枚举类
//2. 有RED,BLUE,BLACK,YELLOW,GREEN这个五个枚举值/对象;
//3. Color有三个属性redValue, greenValue, blueValue,
//4. 创建构造方法,参数包括这三个属性,
//5. 每个枚举值都要给这三个属性赋值,三个属性对应的值分别是
//6. red: 255,0,0 blue:0,0,255 black:0,0.,0 yellow:255,255,0 green:0,255,0
//7. 定义接口,里面有方法show,要求Color实现该接口
//8. show方法中显示三属性的值
//9. 将枚举对象在switch语句中匹配使用
public class Homework0903 {
public static void main(String[] args) {
Color red = Color.RED;
red.show();
switch (red) {
case YELLOW:
System.out.println("匹配到黄色");
break;
case RED:
System.out.println("匹配到红色");
break;
}
}
}
interface ShowColor {
public void show();
}
enum Color implements ShowColor {
RED(255, 0, 0),
BLUE(0, 0, 255),
BLACK(0, 0, 0),
YELLOW(255, 255, 0),
GREEN(0, 255, 0);
private int redValue;
private int greenValue;
private int blueValue;
Color(int redValue, int greenValue, int blueValue) {
this.redValue = redValue;
this.greenValue = greenValue;
this.blueValue = blueValue;
}
@Override
public void show() {
System.out.println("属性值为" + redValue + "," + greenValue + "," + blueValue);
}
}