Java学习笔记 --面向对象进阶

学习内容

static 关键字

final 关键字

枚举

1 static 关键字

static:表示静态,是Java的修饰符,用来修饰(成员变量/成员方法)

1.1 static关键字修饰成员变量

1.1.1 练习 --学生类的共享属性

staticvariabletest1.Student
java 复制代码
package com.itstudy.staticvariabletest1;

public class Student {
   //共享
    String name;//姓名
    int age;//年龄
   //一个班级的学生共享同一个老师
   static String teacherName;//老师姓名

}
staticvariabletest1.Test
java 复制代码
package com.itstudy.staticvariabletest1;

public class Test {
    public static void main(String[] args) {
        /*  学生类的共享属性
            学生有如下属性:姓名,年龄,老师
            一个班级中,所有学生都是共享同一个老师
            第一名学生:小诗诗,19 岁
            第二名学生:小丹丹,20 岁
            最初都是小雯老师上课,有一天小丹丹申请换老师,换成了阿玮老师
            利用 static 模拟上述效果

            关于static需要重点掌握的内容:
              1. 静态变量,被当前类所有对象共享
                   共享:
                       赋值只要赋值一次
                       只要有一个对象修改了静态变量,其他对象再次访问的时候就是修改之后的结果了
              2. 调用方式:
                  方式一:类名调用(推荐)
                  方式二:对象名调用
        */
        //最初都是小雯老师上课
        //student这个类所有对象的teacherName都是小雯老师
        Student.teacherName = "小雯老师";

        Student s1 = new Student();

        s1.name = "小诗诗";
        s1.age = 19;

        Student s2 =new Student();
        s2.name = "小丹丹";
        s2.age = 20;
        s2.teacherName = "阿玮老师";

        System.out.println(s1.name +", " + s1.age+", " + s1.teacherName);
        System.out.println(s2.name + ", " + s2.age+", " + s2.teacherName);

        //用对象名访问静态属性
        System.out.println(s1.teacherName);
        //用类名访问静态属性
        System.out.println(Student.teacherName);
    }
}

1.1.2 练习 -- 判断是否可以用static修饰

答案:老师、饮水机可以用static修饰,因为是共享属性

1.1.3 static关键字的内存解析

输出:小诗诗 23 阿玮老师

null 0 阿玮老师

重点:静态变量是随着类的加载而加载的,优先于对象出现

注:方法执行完出栈,堆内存里对象没有调用时清空,而静态变量和方法区的字节码信息不清空,只有在虚拟机关闭后清空。

1.1.4 static静态变量小结

1.2 static关键字修饰成员方法

1.2.1 工具类

1.2.1 工具类书写方式

1.2.2 工具类练习

toolclasstest.ArrayUtil
java 复制代码
package toolclasstest;
/*定义数组工具类
    需求:
    在实际开发中,经常会遇到一些数组使用的工具类。
    请按照如下要求编写一个数组的工具类完成以下需求:
    提供一个方法 printArr,用于遍历数组。
    格式如下:[10, 20, 50, 34, 100](只考虑整数数组)
    提供一个方法 getAverage,用于返回平均分。(只考虑整数数组)
*/
public class ArrayUtil {
    //私有化构造方法,目的:不让外界创建对象
    private ArrayUtil() {}

    //定义方法(静态)
    /*
      提供一个方法 printArr,用于遍历数组。
           格式如下:[10, 20, 50, 34, 100](只考虑整数数组)
    */

    public static String printArr(int[] arr) {
        //直接打印
        /*System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }*/

        //不直接打印,调用返回值打印
        String result = "[";
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                result = result + arr[i] + "]";
            } else {
                result = result + arr[i] + ", ";
            }
        }
        return result;


    }

    //提供一个方法 getAverage,用于返回平均分。(只考虑整数数组)
    public static double getAverage(int[] arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        double avg = sum * 1.0 / arr.length; //只有乘1.0,才能得到浮点数结果,否则得到整数结果
        return avg;
    }

}
toolclasstest.Test
java 复制代码
package toolclasstest;

public class Test {
    public static void main(String[] args) {

        /*定义数组工具类
            需求:
            在实际开发中,经常会遇到一些数组使用的工具类。
            请按照如下要求编写一个数组的工具类完成以下需求:
            提供一个方法 printArr,用于遍历数组。
            格式如下:[10, 20, 50, 34, 100](只考虑整数数组)
            提供一个方法 getAverage,用于返回平均分。(只考虑整数数组)
        */
        //创建一个数组
        int[] arr = {10, 50, 34, 100};
        //调用数组工具类的方法遍历数组

        // ArrayUtil.printArr(arr); //无返回值方法直接调用打印

        String str = ArrayUtil.printArr(arr);//有返回值方法,需要接收返回值,才能打印
        System.out.println(str);

        int [] arr1={10,20,37,40,50};
        //调用数组工具类的方法返回平均分
        double average = ArrayUtil.getAverage(arr1);
        System.out.println(average);
    }
}

1.3 静态的注意事项

1.3.1 注意事项

1.3.2 静态的内存图

name报错,因为静态方法中没有this来指向对象的内存地址,且没有创建对象来传递地址,导致无法正常访问,即静态方法无法访问非静态变量或者非静态方法

非静态可以调用所有

1.4 static关键字总结

1.5 重新认识main方法

JVM指虚拟机

2 final 关键字

2.1 final关键字介绍

finaltest.Student

java 复制代码
package finaltest;

public class Student {
    private String name;
    private int age;

    //无参构造方法
    public Student() {
    }

    //有参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //get/set方法
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

finaltest.Student1

java 复制代码
package finaltest;

public class Student1 {
    private final String NAME="张三"; //定义为常量,无法修改属性值 且无法使用this关键词
    final int AGE=18;  //为了方便调用,去掉private修饰符

    //无参构造方法
    public Student1() {
    }


    //get/set方法
    public String getName() {
        return NAME;
    }

    public int getAge() {
        return AGE;
    }

}

finaltest.FinalTest

java 复制代码
package finaltest;

public class FinalTest {
    public static void main(String[] args) {
        /*
         * final  修饰变量,此时叫做常量
         *   特点1:只能被赋值一次,一旦赋值,无法再次修改
         *   特点2:常量名大写,多个单词之间用下划线隔开
         *
         * 细节:
         *     基本数据类型:
         *         byte short int long float double char boolean
         *         变量里面记录的是真实的数据
         *          final int a =10;  此时变量里面记录的数据无法发生改变
         *     引用数据类型:
         *         除了上面四类八种,其他所有的数据类型都是引用类型 例:int[]、 String[]、Student
         *
         *         stu里面记录对象的内存地址,不可改变的是stu记录的内存地址
         *         而对象里面的属性值,是可以发生改变的
         *          final Student stu = new Student();
         *      综上所述:
         *          final修饰哪个变量,这个变量里面记录的内容就无法再次发生改变
         * */

        //1.定义一个常量
        final int NUMBER = 100;

        //2.使用常量
        System.out.println(NUMBER + 200);

        // 不可修改赋值(报错)
        // NUMBER=200;

        //定义一个引用数据类型的常量
        final Student STU = new Student("张三", 18);
        // STU=new Student();(报错)  无法修改对象的内存地址

        // 可以修改对象里面的属性值
        STU.setName("李四");
        STU.setAge(20);
        System.out.println(STU.getName());
        System.out.println(STU.getAge());

        //定义一个引用数据类型的常量
        final Student1 STU1 = new Student1();
        System.out.println(STU1.getName());
        System.out.println(STU1.AGE);


    }
}

2.2 final的内存图

2.3 练习 -- 常量的练习

finaltest.Circle

java 复制代码
package finaltest;

public class Circle {
    /*
    定义一个 Javabean 类描述圆
    属性:半径和圆周率
    行为:计算圆的面积和周长
    */

    // 定义属性
    private double radius; // 半径
    private final double PI = 3.141592653589793238462; // 圆周率

    // 无参构造方法
    public Circle() {
    }

    // 有参构造方法
    public Circle(double radius) {
        this.radius = radius;
    }

    //get/set方法


    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double getPI() {
        return PI;
    }

    // 定义行为
    // 计算圆的面积
    public double getArea() {
        return radius * radius * PI;
    }

    // 计算圆的周长
    public double getLength() {
        return 2 * PI * radius;
    }
}

finaltest.FinalTest2

java 复制代码
package finaltest;

public class FinalTest2 {
    public static void main(String[] args) {
       /* 常量的练习
        定义一个 Javabean 类描述圆
        属性:半径和圆周率
        行为:计算圆的面积和周长
       */

        // 定义一个圆对象
        Circle c1 = new Circle(5.0);

        // 获取圆里面的属性
        System.out.println(c1.getRadius());
        System.out.println(c1.getPI());

        // 获取圆的面积
        System.out.println(c1.getArea());
        // 获取圆的周长
        System.out.println(c1.getLength());




    }
}

3 枚举

3.1 什么是枚举

3.2 枚举的定义格式

3.3 枚举定义练习 -- 订单状态

enumtest.OrderState

java 复制代码
package enumtest;

/*电商项目中,订单的状态只有以下 6 种,请编写代码实现。
待支付、处理中、已发货、配送中、已送达、已取消。*/

public enum OrderState {

    // 在枚举类的第一行,把所有的对象都罗列出来了
    PAYMENT_PENDING("待支付"),//待支付
    PROCESSING("处理中"),//处理中
    SHIPPED("已发货"),//已发货
    OUT_OF_FOR_DELIVERY("配送中"),//配送中
    DELIVERED("已送达"),//已送达
    CANCELLED("已取消");////已取消

    // 有参构造方法
    private String name;

    // 枚举类的构造方法默认使用 private 修饰,就算不写,虚拟机也会加上 private
    private OrderState(String name) {
        //每一个枚举项,都是该枚举类的对象(每一个对象都是通过构造方法创建出来的)
        System.out.println("看看我执行了吗?"+name); //验证构造方法是否执行了
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

enumtest.Test

java 复制代码
package enumtest;

public class Test {
    public static void main(String[] args) {
       /* 订单的状态
        电商项目中,订单的状态只有以下 6 种,请编写代码实现。
        待支付、处理中、已发货、配送中、已送达、已取消。*/

        OrderState o1 = OrderState.PAYMENT_PENDING;
        System.out.println(o1);

        //匹配
        switch (o1) {
            case PAYMENT_PENDING -> System.out.println("待支付状态");
            case PROCESSING -> System.out.println("处理中");
            case SHIPPED -> System.out.println("已发货");
            case OUT_OF_FOR_DELIVERY -> System.out.println("配送中");
            case DELIVERED -> System.out.println("已送达");
            case CANCELLED ->  System.out.println("已取消");
        }

    }
}

3.4 枚举的注意事项

enumtest.OrderState

java 复制代码
package enumtest;

/*电商项目中,订单的状态只有以下 6 种,请编写代码实现。
待支付、处理中、已发货、配送中、已送达、已取消。*/

public enum OrderState {

    // 在枚举类的第一行,把所有的对象都罗列出来了
    PAYMENT_PENDING("待支付"),//待支付
    PROCESSING("处理中"),//处理中
    SHIPPED("已发货"),//已发货
    OUT_OF_FOR_DELIVERY("配送中"),//配送中
    DELIVERED("已送达"),//已送达
    CANCELLED("已取消");////已取消

    // 有参构造方法
    private String name;

    // 枚举类的构造方法默认使用 private 修饰,就算不写,虚拟机也会加上 private
    private OrderState(String name) {
        //每一个枚举项,都是该枚举类的对象(每一个对象都是通过构造方法创建出来的)
        System.out.println("看看我执行了吗?"+name); //验证构造方法是否执行了
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

enumtest.Test2

java 复制代码
package enumtest;

public class Test2 {
    public static void main(String[] args) {
        /*
        枚举的注意事项
            1.每一个枚举项,都是该枚举类的对象(每一个对象都是通过构造方法创建出来的)
            2.枚举项在底层其实就是常量,默认用 public static final 修饰
              (终端输入 Javap OrderState.class查看底层逻辑)
            3.枚举类的第一行上必须是枚举项,枚举项之间用逗号隔开,以分号作为结尾
            4.枚举类的构造方法必须是 private 修饰,不让外界创建本类的对象
            5.编译器会给枚举类新增两个默认存在的方法:values (),valueOf ()

            values():表示获取本类所有的枚举项
            valueOf(): 表示获取一个指定的枚举项
        */

        OrderState o1 = OrderState.CANCELLED;
        System.out.println(o1.getName());

        OrderState[] arr = OrderState.values();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

        OrderState o2 = OrderState.valueOf("SHIPPED");
        System.out.println(o2.getName());
    }
}
相关推荐
weigangwin1 小时前
DSPy 采用笔记:先证明 LLM 程序合同,再谈 Prompt 优化
笔记·prompt
写了20年代码的老程序员1 小时前
Java Lambda 类型安全查询是怎么实现的?从字节码层面拆一遍
java·开源
智者知已应修善业1 小时前
【P12159蓝桥杯数组翻转】2025-4-24
c语言·c++·经验分享·笔记·算法·蓝桥杯
摇滚侠1 小时前
Apache Skywalking 实战 阅读笔记 第三章
笔记·apache·skywalking
唐青枫1 小时前
Java RabbitMQ 实战指南:从交换机、队列到可靠消息处理
java
卓怡学长1 小时前
w272基于springboot便民医疗服务小程序
java·spring boot·spring·小程序·intellij-idea
一方~2 小时前
权限系统设计
java
β添砖java2 小时前
Ollama工具学习
学习
盐焗鹌鹑蛋2 小时前
【C++】多态
java·jvm·c++