自学内容网 自学内容网

JAVA学习笔记——第十一章 枚举和注解

一、引出枚举类

1.先看一个需求demo

package com.hspedu.enum_;

public class Enumration01 {
    public static void main(String[] args) {
        Season Spring = new Season("春天", "温暖");
        Season Summer = new Season("夏天", "炎热");
        Season Autumn = new Season("秋天", "潮湿");
        Season Winter = new Season("冬天", "寒冷");
        //对于季节来说,他的对象是固定的四个不会有更多,如果按照这个设计类的思路,不能体现季节是固定的四个对象。
        // 因此这样的设计不好
        Autumn.setName("XXX");
        Autumn.setDesc("hahaha");
        //可以引出枚举类,把具体的对象一个一个列举出来的类
        //称为枚举类
    }
}

class Season {
    private String name;
    private String desc;//描述

    public Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.创建Season对象有如下的特点:

1).季节的值是有限的几个值(spring,summer,autumn。wiinter)

2).只读,不需要修改

3.解决方案-枚举

1)枚举对应英文enumeration

2)枚举是一组常量的集合

3)枚举是一种特殊的类,里面只包含一组有限的特定的对象

4.枚举的两种实现方式

1.自定义类实现枚举

package com.hspedu.enum_;

public class Enumration02 {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
    }
}
//演示自定义枚举实现
//1.构造器私有化,防止直接被new出来
//2.把setXXX相关方法去掉,防止属性被修改
//3.在Season内部,直接创建固定的对象
//4.可以加一个final,final+static可以跳过类加载,调用final+ static的变量,你不可能去修改,可以不需要类加载,底层优化,避免了类加载
//补充:这里出现了误会,去看了前面的final关键字。其实这里并没有跳过类加载,因为它new了一定会进行类加载,这里只是想说明常量不能修改
class Season {
    private String name;
    private String desc;//描述

    //定义了四个对象
    public final static Season SPRING = new Season("春天","温暖");//常量必须大写规范
    public final static Season SUMMEE = new Season("夏天","炎热");
    public final static Season AUTUMN = new Season("秋天","潮湿");
    public final static Season WINTER = new Season("冬天","寒冷");

    private Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
    public String getDesc() {
        return desc;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

2. 使用关键字enum实现类加载

package com.hspedu.enum_;

public class Enumeration3 {
    public static void main(String[] args) {
        System.out.println(Season2.SPRING);
        System.out.println(Season2.SUMMER);
    }
}
//演示关键字实现枚举
enum Season2 {
    //定义了四个对象
//    public final static Season2 SPRING = new Season2("春天","温暖");//常量必须大写规范
//    public final static Season2 SUMMEE = new Season2("夏天","炎热");
//    public final static Season2 AUTUMN = new Season2("秋天","潮湿");
//    public final static Season2 WINTER = new Season2("冬天","寒冷");
//如果使用enum来实现枚举类
    //1.使用关键字替代class
    //2.public final static Season2 SPRING = new Season2("春天","温暖");直接使用    SPRING("春天","温暖");
    //其实格式就是常量名(SPRING)+传给构造器的参数(("春天","温暖"))
    //3.如果有多个常量(对象),使用逗号间隔即可
    //4.如果使用enum实现枚举。要求定义的常量对象写在最前面
    SPRING("春天","温暖"),Winter("冬天","寒冷"),SUMMER("夏天","炎热"),AUTUMN("秋天","潮湿");
    private String name;
    private String desc;//描述
    private Season2(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
    public String getDesc() {
        return desc;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

5.enum关键字实现枚举-快速入门

-

对于1.,使用javap来证明 除了继承以外往下看都是public staitc  final ,还有一些隐藏的属性啥的

对于3:如果调用无参构造器,创建常量对象,则可以省略()

what,SPRING("春天", "温暖"), Winter("冬天", "寒冷"), SUMMER("夏天", "炎热"), AUTUMN("秋天", "潮湿");
    //看上面如果调用无参构造器,创建常量对象,则可以省略()
    private String name;
    private String desc;//描述

    private Season2(){
        
    }
    private Season2(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

6.课堂练习

 这个是对的,这里其实就是调用了Gender这个类的无参构造器,因为在这个类里面没有写其他的构造器,所以默认的无参构造器是存在的。

这里要考虑,这个BOY默认是public static final修饰的,static是类成员

第三行其实就是输出Gender2的tostring方法,但是它没有只能向上找分类Enum,Enum中(源码)的注释说了这个name就是enum常量的名称 ,所以第三行返回的就是BOY

且static说明这个BOY是一个静态对象,所以只有一个地址所以最后是true,其实感觉和静态关系也不大,本来就是同一个对象的两个引用指向它

 7.java_Enum常用方法

package com.hspedu.enum_;/*
 * @author SHOWY
 */

public class Enummethod03 {
    public static void main(String[] args) {
        //使用Season2枚举类来演示各种方法
        Season2 autumn = Season2.AUTUMN;
        //输出枚举对象的名称
        System.out.println(autumn.name());
        //输出的是该枚举对象的次序(第几个编号从0开始),后面可以用这个作比较
        System.out.println(autumn.ordinal());
        //返回的是Seasons2的数组,含有定义的所有枚举对象
        Season2[] values = Season2.values();
        //遍历取出枚举对象
        for (Season2 season : values) {//增强for循环
            System.out.println(season);
             }
        //valuesof把字符串转成枚举对象,要求字符串必须为已有的常量名
        //执行流程根据输入的名称到Season2的枚举对象查找,如果找到返回,如果没有报错
        Season2 autumn1 = Season2.valueOf("AUTUMN");
        System.out.println("autunmn1" + autumn1);
        System.out.println(autumn1 ==autumn);
        //compareto比较两个枚举常量,就是比较编号
        //就是把Season2.AUTUMN和Season2.SUMMER枚举对象的编号比较,发现其实是两个编号的差值
        System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER));
    }
}

 8.java_Enum课堂练习

package com.hspedu.enum_;/*
 * @author SHOWY
 */

import java.time.temporal.WeekFields;

public class EnumExercise2 {
    public static void main(String[] args) {
        Week week[] = Week.values();
        System.out.println("所有星期的信息如下");
        for(Week w: week){
            System.out.println(w);
        }
    }
}


enum Week{
    //创建week枚举对象
    MONDAY("星期一"),   TUESDAY("星期二"),   WEDNESDAY("星期三"),   THURSDAY("星期四"),   FRIDAY("星期五"),
    SATURDAY("星期六"),   SUNDAY("星期日");
    private String name;

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


    @Override
    public String toString() {
        return name;
    }
}

9.enum实现接口

二、注解 

1.注解的理解

 

2.Java_Override注解

1.介绍

2.使用说明(总结)

 3.Java_Deprecated注解

package com.hepedu.deprecated;/*
 * @author SHOWY
 */

public class deprecated
{
    public static void main(String[] args) {
        A a = new A();
        a.hi();
    }
}
//1.@Deprecated修饰某个元素,表示该元素
//2.不推荐使用但是能用
//3.可以修饰方法、类、包、参数等等
//4.可以做版本升级过渡使用
@Deprecated
class A{

    public int n1 = 10;
    @Deprecated
    public void hi(){
        System.out.println("hi");
    }
}

4.Java_SuppressWarnings注解

当我们不希望看到这些警告的时候,可以用SuppressWarnings注解来抑制这个警告信息
package com.hepedu.deprecated;/*
 * @author SHOWY
 */

import java.util.ArrayList;
import java.util.List;

public class SuppressWarnings {

    //1.当我们不希望看到这些警告的时候,可以用SuppressWarnings注解来抑制这个警告信息
    //2.在("")中可以写入你希望抑制的警告信息,直接给个all就行
    //3.关于SuppressWarnings的作用范围和放置的位置相关,比如放置
    //在main方法,那么抑制警告的范围就是main,也可以直接放在类上
    //4.看源码可以看见有一个 String[] value();说明该注解类可以设置一个数组
    @java.lang.SuppressWarnings("all")
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        int i;
        System.out.println(list.get(1));
    }
}

5.四种元注解

1.基本介绍

2.Retention注解

2.Target注解

 3.Documented注解

形成文档的时候能保留

 4.Inherited注解

注解具有继承性

 三、练习

3.1 练习1

color是静态的上来就有一个空间,而静态static只在类加载的时候执行,所以在new c1的时候这个color不再变了,所以答案是9.0,red 100.0,red

3.2 练习2

(简单,跟着步骤写就行)

package com.test;/*
 * @author SHOWY
 */

public class lianxi2 {
}
class Frock{
    private static int currentNum = 100000;
    private int serialNumber;

    public Frock() {
        serialNumber = getNextNum();
    }

    public int getSerialNumber() {
        return serialNumber;
    }

    public static int getNextNum(){
        currentNum +=  100;
        return currentNum;
    }

}
class TestFrock{
    public static void main(String[] args) {
        System.out.println(Frock.getNextNum());//100100
        System.out.println(Frock.getNextNum());//100200
        Frock frock = new Frock();//100300
        Frock frock1 = new Frock();//100400
        Frock frock2 = new Frock();//100500
        System.out.println(frock.getSerialNumber());
        System.out.println(frock1.getSerialNumber());
        System.out.println(frock2.getSerialNumber());
    }
}

3.3 练习3 

有点简单,就是有一个方法事abstract的,记得给这个类也是抽象类

package com.test;/*
 * @author SHOWY
 */

public class liaxi3 {
    public static void main(String[] args) {
        Animal cat = new Cat();
        Animal dog = new Dog();
        cat.shout();
        dog.shout();
    }
}

abstract class Animal{//抽象方法所以事抽象类
     public abstract void shout();
}

class Cat extends Animal{
    @Override
    public void shout() {
        System.out.println("小猫喵喵叫");
    }
}
class Dog extends Animal{
    @Override
    public void shout(){
        System.out.println("小狗汪汪叫");
    }
}

3.4 练习4(很重要匿名内部类)

package com.test;/*
 * @author SHOWY
 */

public class lianxi4 {
    public static void main(String[] args) {
        Cellphone cellphone = new Cellphone();
        cellphone.testwork(new Icalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1 + n2;
            }
        },2,3);
        cellphone.testwork(new Icalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1 * n2;
            }
        },3,4);
    }
}

interface Icalculate{
        public double work(double n1,double n2);
}
class Cellphone{
    //当我们调用testWork方法时,直接传入了一个实现ICalculate的接口的匿名内部类,该匿名内部类可以灵活实现work方法完成不同的计算任务
    public void testwork(Icalculate icalculate, double n1,double n2){
        double result = icalculate.work(n1,n2);
        System.out.println("计算后的结果是" + result);
    }
}

3.5 练习5 

package com.test;/*
 * @author SHOWY
 */

public class lianxi5 {
}
class A {
    private String name = "cpy";

    public void f1() {
        class B {//这个类在方法体中,局部内部类
            private final String name = "gzh";

            public void show() {
                System.out.println("NAME" + name +"外部类的name" + A.this.name);
//重名了如果要调用外部类的私有变量就类.this.属性名来指定
            }
        }
    }
}

3.6 练习6(很难)

这道题还是有点难度大的,乱乱的

值得注意的点,比如在创建交通工具工厂类的时候,后续不需要创建对象,只需要加方法,所以设置为static,然后为了马是同一只马,也做了操作

//VehiclesFactory
package com.test;/*
 * @author SHOWY
 */

public class VehiclesFactory {
    private static Horse  horse = new Horse();
    private VehiclesFactory() {}//防止创建对象
    //创建交通工具工厂类,有两个方法分别获得交通工具Horse和Boat
    //这里将方法做成static比较方便,不需要创建对象
    //为了船每次得到新的,马是老的同一只
    public static Horse getHorse(){
        return horse;
    }
    public static Boat getBoat(){
        return new Boat();
    }

}

//Horse
package com.test;/*
 * @author SHOWY
 */

public class Horse implements Vehicles{
    @Override
    public void work() {
        System.out.println("一般情况下使用马儿前进");
    }
}
//Boat
package com.test;/*
 * @author SHOWY
 */

public class Boat implements Vehicles{
    @Override
    public void work() {
        System.out.println("过河的时候使用小船");
    }
}
//Interface Vehicles  
package com.test;/*
 * @author SHOWY
 */

public interface Vehicles {
    public void work();

}
//Person
package com.test;/*
 * @author SHOWY
 */

public class Person {
    private String name;
    private Vehicles vehicles;//接口当属性第一次见!

    public Person(String name, Vehicles vehicles) {
        this.name = name;
        this.vehicles = vehicles;
    }

    //实例化Person对象“唐僧”,要求一般情况下用horse作为交通工具,遇到大河时用Boat作为交通工具
    //这里涉及一个编程思路,就是可以把具体的要求封装成方法
    //先得到船
    //思考一个问题,如果不浪费在构建对象的时候,传入的交通工具对象
    public void passRiver() {
//        Boat boat = VehiclesFactory.getBoat();
//        boat.work();
    if(!(vehicles instanceof Boat)){
        vehicles = VehiclesFactory.getBoat();
    }
        vehicles.work();
    }
    public void common(){
//        Horse horse = VehiclesFactory.getHorse();
//        horse.work();
        if(!(vehicles instanceof Horse)){
            vehicles = VehiclesFactory.getHorse();
        }
        vehicles.work();
    }
}
//主函数
package com.test;/*
 * @author SHOWY
 */

public class lianxi6 {
public static void main(String[] args) {
    Person tang =  new Person("唐僧",new Horse());
    tang.common();
    tang.passRiver();
}
}

补充:他要过一次火焰山

 这时候可以用到匿名内部类,假设他就过一次火焰山,除了添加firehill类以外

package com.test;/*
 * @author SHOWY
 */

public class Person {
    private String name;
    private Vehicles vehicles;//接口当属性第一次见!

    public Person(String name, Vehicles vehicles) {
        this.name = name;
        this.vehicles = vehicles;
    }

    //实例化Person对象“唐僧”,要求一般情况下用horse作为交通工具,遇到大河时用Boat作为交通工具
    //这里涉及一个编程思路,就是可以把具体的要求封装成方法
    //先得到船
    //思考一个问题,如果不浪费在构建对象的时候,传入的交通工具对象
    public void passRiver() {
//        Boat boat = VehiclesFactory.getBoat();
//        boat.work();
    if(!(vehicles instanceof Boat)){
        vehicles = VehiclesFactory.getBoat();
    }
        vehicles.work();
    }
    public void common(){
//        Horse horse = VehiclesFactory.getHorse();
//        horse.work();
        if(!(vehicles instanceof Horse)){
            vehicles = VehiclesFactory.getHorse();
        }
        vehicles.work();
    }
    public void testwork(Vehicles vehicles){
          vehicles = VehiclesFactory.getfirehill();//搞到vehicles以后调用work
          vehicles.work();
    }
}
package com.test;/*
 * @author SHOWY
 */

public class lianxi6 {
public static void main(String[] args) {
    Person tang =  new Person("唐僧",new Horse());
    tang.common();
    tang.passRiver();
    tang.testwork(new Vehicles() {
        @Override
        public void work() {
            System.out.println("火焰山坐飞机走了");
        }
    });
}
}

3.7 练习7(成员内部类

这个题就是一个成员内部类,关键点在于在这类中写一个返回Air对象的方法!!! 

package com.test;/*
 * @author SHOWY
 */

public class lianxi7 {
    public static void main(String[] args) {
        //实例化不同的对象
        Car car = new Car(60);
        car.getAir().flow();
        Car car1 = new Car(-1);
        car1.getAir().flow();
    }

}
class Car{
    private double temperature;

    public Car(double temperature) {
        this.temperature = temperature;
    }

    class Air{//成员内部类能监控外部类的属性
        public void flow(){
            if(temperature > 40){
                System.out.println("温度大于了40,空调吹冷气。。");
            }else if(temperature < 0){
                System.out.println("温度小于0,空调吹暖气");
            }
            else{
                System.out.println("温度正常,关系空调");
            }
        }
    }
    //提供一个方法,返回Air对象
    public Air getAir(){
        return new Air();
    }
}

3.8 练习8(好题)

 重点在switch中枚举对象的匹配

package com.test;/*
 * @author SHOWY
 */

public class lianxi8
{
    public static void main(String[] args){
        //演示枚举值得switch使用,switch中放入枚举对象,在case中直接写在枚举类中定义的枚举对象即可
        Color green = Color.GREEN;
        green.show();

        switch (green){
            case RED:
                System.out.println("匹配黄色");
                break;
            case BLACK:
                System.out.println("匹配到黑色");
                break;
            default:
                System.out.println("没有匹配到");
        }
}


}
interface Myinterface{
    public void show();
}
enum Color implements Myinterface{
    RED(255,0,0),BLUE(0,0,255),BLACK(0,0,0),YELLOW(255,255,0),GREEN(0,255,0);
    private int redCalue;
    private int greenCalue;
    private int blueCalue;

        Color(int redCalue, int greenCalue, int blueCalue) {
        this.redCalue = redCalue;
        this.greenCalue = greenCalue;
        this.blueCalue = blueCalue;
    }

    @Override
    public void show() {
        System.out.println("属性值为" + redCalue + "," + greenCalue + "," + blueCalue);
    }
}


原文地址:https://blog.csdn.net/showy0/article/details/143095503

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!