Просмотр исходного кода

feat: 新增20260721课堂笔记及授课代码分析——构造方法(构造器)、构造方法重载、课后作业回顾(Fisher-Yates洗牌/回文数等)

WanJL 20 часов назад
Родитель
Сommit
c4e6588263

+ 2 - 0
README.md

@@ -28,6 +28,7 @@
 | 2026-07-16 | [多维数组、forEach、Arrays工具类、三种排序算法(冒泡/选择/插入)与 Scanner 键盘输入](./课堂笔记/01-JavaSE基础-笔记/20260716-笔记.md) |
 | 2026-07-17 | [Java方法4种声明方式(无参无返回值/有参无返回值/有参有返回值/无参有返回值)、方法中调用方法、数组作为方法参数、Random随机数类、Random+方法综合练习、三种排序算法复习、Scanner 学生信息采集系统](./课堂笔记/01-JavaSE基础-笔记/20260717-笔记.md) |
 | 2026-07-20 | [面向对象基础:类与对象、成员变量与成员方法、创建对象与使用成员](./课堂笔记/01-JavaSE基础-笔记/20260720-笔记.md) |
+| 2026-07-21 | [构造方法(构造器):构造方法概念、格式、重载、默认构造方法、有参构造方法、private 构造方法](./课堂笔记/01-JavaSE基础-笔记/20260721-笔记.md) |
 
 ## 二、授课代码
 
@@ -42,6 +43,7 @@
 | 2026-07-16 | 多维数组、forEach、Arrays工具类、三种排序算法(冒泡/选择/插入)与 Scanner 键盘输入 | `c260716` | [默认包](./授课代码/c260716/src/) |
 | 2026-07-17 | Java方法4种声明方式、数组作为方法参数、Random随机数类、在线OJ编码模板、三种排序算法复习、Scanner学生信息采集系统(BMI计算) | `c260717` | [默认包](./授课代码/c260717/src/) |
 | 2026-07-20 | 面向对象基础:类与对象、成员变量与成员方法、创建对象与使用成员、对象地址输出、成员变量 vs 局部变量、对象引用与内存共享、对象数组、循环创建对象并存入数组、多个类协同建模(古诗场景/交通场景)、封装(private/setter/getter/this关键字/权限修饰符)、包(Package)声明与同包访问、方法返回对象数组、综合应用(学生管理+随机抽取) | `c260720` | [`p1`](./授课代码/c260720/src/p1/) / [`p2`](./授课代码/c260720/src/p2/) |
+| 2026-07-21 | 构造方法(构造器):构造方法概念与格式、默认构造方法、构造方法重载、有参构造方法、private 构造方法、this 关键字在构造方法中的应用、Fisher-Yates 洗牌算法(数组随机打乱)、封装与 setter 校验复习、回文数判断算法 | `c260721` | [`course`](./授课代码/c260721/src/course/) / [`homework/c260717`](./授课代码/c260721/src/homework/c260717/) / [`homework/c260720`](./授课代码/c260721/src/homework/c260720/) |
 
 ## 三、课堂练习题
 

+ 30 - 0
授课代码/c260721/.gitignore

@@ -0,0 +1,30 @@
+### IntelliJ IDEA ###
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+.kotlin
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 84 - 0
授课代码/c260721/src/course/Demo01.java

@@ -0,0 +1,84 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Demo01
+ * @description 构造方法(构造器)
+ * @create 2026/7/21
+ */
+public class Demo01 {
+    /*
+        public class Person{
+            private String name;
+            private int age;
+            private String gender;
+
+            // getter & setter 省略
+        }
+        public class PersonTest{
+            public static void main(String[] args){
+                Person p=new Person();  //创建 人 对象 --- 造人
+                p.setName("张三");    //人出生后 取名 ,符合现实逻辑,没问题
+                p.setGender("男"); // 人出生后,再设置性别,代码没问题,但是不符合现实逻辑
+                //需要 在创建人的时候,就要赋值性别和年龄等属性
+                // 我们在创建对象的时候, 某些属性 是要随着 构造对象的同时而定义
+            }
+        }
+        那么就需要使用到 构造器(构造方法)
+        构造方法的格式:
+            构造方法的方法名和类名完全一致,不仅相同而且大小写一样
+            没有返回值类型,连void都没有,因为返回的就是新构造出来的对象
+            没有具体的返回值,所以也不能使用return带回结果数据, 因为直接返回对象。
+
+         public class Person{
+            private String name;
+            private int age;
+            private String gender;
+
+            构造方法的格式:
+            访问权限修饰符 类名(){
+
+            }
+
+            public Person(){
+
+            }
+
+            // getter & setter 省略
+        }
+
+        什么时候会执行构造方法?
+            当我们创建对象的时候,会调用。每当创建一个对象,就会执行一次构造方法完成对象的构造。
+            不能手动调用构造方法
+
+        构造方法的作用:
+            用来给对象的属性进行初始化赋值。
+
+        注意:
+            实际上Java中所有的类,创建对象的时候,都会默认调用一个构造方法
+            实际上Java中所有的类,都默认有一个隐藏的构造方法。
+            然后当我们定义构造方法的时候,我们定义的会【覆盖】默认隐藏的构造方法
+            在创建对象的时候,其实就是调用构造方法实现创建对象的。
+            如果这个类的构造方法,被设置了权限,那么外部干脆就创建不了对象
+            每个类默认带有的隐藏大构造方法,的访问权限修饰符 是和类的修饰符相同的。
+            类如果是使用public 那么构造方法也是public
+            当然,我们可以在定义构造方法的时候,设置其他的修饰符权限
+
+        有参构造方法
+            构造方法中也可以定义参数,跟普通方法一样,可以通过构造方法为私有变量赋值
+
+             //构造方法
+            public Person(){
+                System.out.println("这是一个构造方法....我开始造人啦");
+                //写死代码..直接给性别赋值
+                this.gender="男";
+            }
+            public Person(String gender){
+                this.gender=gender;
+            }
+            构造方法可以有多个同名的构造方法,只要【参数类型不同】、【参数个数不同】就可以。这种情况称为 【构造方法重载】
+            如果参数类型相同,个数相同,参数名不同,是不算的。
+     */
+}

+ 61 - 0
授课代码/c260721/src/course/Person.java

@@ -0,0 +1,61 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Person
+ * @description
+ * @create 2026/7/21
+ */
+public class Person {
+
+    private String name;
+    private int age;
+    private String gender;
+
+    //构造方法
+    public Person(){
+        System.out.println("这是一个构造方法....我开始造人啦");
+        //写死代码..直接给性别赋值
+        this.gender="男";
+    }
+    public Person(String gender){
+        this.gender=gender;
+    }
+    public Person(String name,String gender){
+        this.name=name;
+        this.gender=gender;
+    }
+    public Person(String name,int age,String gender){
+        this.name=name;
+        this.age=age;
+        this.gender=gender;
+    }
+
+
+    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;
+    }
+
+    public String getGender() {
+        return gender;
+    }
+
+    public void setGender(String gender) {
+        this.gender = gender;
+    }
+}
+

+ 30 - 0
授课代码/c260721/src/course/PersonTest.java

@@ -0,0 +1,30 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title PersonTest
+ * @description
+ * @create 2026/7/21
+ */
+public class PersonTest {
+    public static void main(String[] args) {
+        //当创建对象的时候,会自动的调用并执行对应的构造方法
+        Person p=new Person();
+        System.out.println(p.getGender());
+
+        // 当创建一个类的对象其实就是调用这个类的默认构造方法:
+        // new Person();    // 严格来讲,这一步才是创建对象,
+        // 其实就是 通过 new 关键字 调用了 Person 类的默认构造方法,来创建的对象。
+        // Person p=new Person() 其实就是把 new Person() 创建的对象的地址,赋值给 Person类型的p变量
+        //所以,我们直接输出p 或者 输出new Person() 都会返回一个地址
+        System.out.println(p);
+        System.out.println(new Person());
+        // 调用带有参数的构造方法,并且为参数赋值
+        Person p1=new Person("女");
+        System.out.println(p1.getGender());
+
+    }
+
+}

+ 33 - 0
授课代码/c260721/src/course/Student.java

@@ -0,0 +1,33 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Student
+ * @description
+ * @create 2026/7/21
+ */
+public class Student {
+    // 如果给构造方法设置了私有权限,则外部无法创建当前类的对象
+    /*
+    private Student(){
+        System.out.println("构造学生对象....");
+    }
+    */
+    private String name;
+    private int age;
+    private String gender;
+    //创建无参构造方法
+    public Student() {
+    }
+
+    /*
+            有参构造方法
+         */
+    public Student(String name,int age,String gender){
+        this.name=name;
+        this.age=age;
+        this.gender=gender;
+    }
+}

+ 15 - 0
授课代码/c260721/src/course/StudentTest.java

@@ -0,0 +1,15 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title StudentTest
+ * @description
+ * @create 2026/7/21
+ */
+public class StudentTest {
+    public static void main(String[] args) {
+        Student s=new Student("张三",25,"男");
+    }
+}

+ 32 - 0
授课代码/c260721/src/homework/c260717/Demo_08.java

@@ -0,0 +1,32 @@
+package homework.c260717;
+
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Demo_08
+ * @description 题目8:数组随机打乱
+ * @create 2026/7/21
+ */
+public class Demo_08 {
+    public static void shuffleArray(int[] arr) {
+        Random ran = new Random();
+        // 从后往前遍历,实现 Fisher-Yates 洗牌
+        for (int i = arr.length-1; i>1 ; i--) {
+            int j=ran.nextInt(i+1);
+                int t=arr[i];
+                arr[i]=arr[j];
+                arr[j]=t;
+        }
+    }
+
+    public static void main(String[] args) {
+        int[] arr = {1, 2, 3, 4, 5, 6, 7};
+        System.out.println("打乱前:" + Arrays.toString(arr));
+        shuffleArray(arr);
+        System.out.println("打乱后:" + Arrays.toString(arr));
+    }
+}

+ 47 - 0
授课代码/c260721/src/homework/c260720/Emp.java

@@ -0,0 +1,47 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Emp
+ * @description
+ * @create 2026/7/21
+ */
+public class Emp {
+    private String id;
+    private String name;
+    private double salary;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public double getSalary() {
+        return salary;
+    }
+
+    public void setSalary(double salary) {
+        if (salary<0){
+            System.out.println("薪资不能为负数");
+        }else {
+            this.salary = salary;
+        }
+    }
+
+    public void work(){
+        System.out.println("工号"+id+"的员工"+name+"正在工作......");
+    }
+}

+ 19 - 0
授课代码/c260721/src/homework/c260720/EmpTest.java

@@ -0,0 +1,19 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title EmpTest
+ * @description
+ * @create 2026/7/21
+ */
+public class EmpTest {
+    public static void main(String[] args) {
+        Emp emp=new Emp();
+        emp.setId("a1001");
+        emp.setName("张三");
+        emp.setSalary(-10000);
+        emp.work();
+    }
+}

+ 56 - 0
授课代码/c260721/src/homework/c260720/MathTools.java

@@ -0,0 +1,56 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title MathTools
+ * @description
+ * @create 2026/7/21
+ */
+public class MathTools {
+    /**
+     * 输出 1~100 之间的所有质数,每行输出 5 个数
+     */
+    public void printPrime() {
+
+    }
+
+    /**
+     * 计算并输出 n~m 之间所有整数的累加和
+     *
+     * @param n
+     * @param m
+     */
+    public void printSum(int n, int m) {
+
+    }
+
+    /**
+     * 判断一个整数是否为回文数(正着读反着读一样),返回 true/false
+     * isPalindrome() 需测试至少 3 个数(如 12321、12345、1221)
+     * @param num
+     * @return
+     */
+    public boolean isPalindrome(int num) {
+        //设置一个永远不会变的数,跟后面反着的数进行比较
+        int a=num;
+        int sum=0;
+        //我们不知道要循环多少次,所以使用
+        while(num>0){
+            int b=num%10;   //获取到num的最后一个数
+            sum=sum*10+b;   //获得最后1位数
+            num/=10;    //缩小10倍
+        }
+        return sum == a ;
+    }
+
+    /**
+     * 使用 Random 生成一个 1~100 之间的幸运数字并返回
+     *
+     * @return
+     */
+    public int getLuckyNumber() {
+        return 0;
+    }
+}

+ 15 - 0
授课代码/c260721/src/homework/c260720/SortUtils.java

@@ -0,0 +1,15 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title SortUtils
+ * @description
+ * @create 2026/7/21
+ */
+public class SortUtils {
+    public void bubbleSort(int[] arr){
+
+    }
+}

+ 48 - 0
授课代码/c260721/src/homework/c260720/Student.java

@@ -0,0 +1,48 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Student
+ * @description
+ * @create 2026/7/21
+ */
+public class Student {
+    private String name;
+    private int age;
+    private String className;
+
+    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;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    public void showInfo(){
+        System.out.println("姓名:"+this.name);
+        System.out.println("年龄:"+this.age);
+        System.out.println("班级:"+this.className);
+    }
+    public void study(String course){
+        System.out.println(this.name+"正在学习"+course);
+    }
+}

+ 20 - 0
授课代码/c260721/src/homework/c260720/StudentTest.java

@@ -0,0 +1,20 @@
+package homework.c260720;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title StudentTest
+ * @description
+ * @create 2026/7/21
+ */
+public class StudentTest {
+    public static void main(String[] args) {
+        Student s=new Student();
+        s.setName("张三");
+        s.setAge(25);
+        s.setClassName("J260713");
+        s.showInfo();
+        s.study("Java");
+    }
+}

+ 515 - 0
课堂笔记/01-JavaSE基础-笔记/20260721-笔记.md

@@ -0,0 +1,515 @@
+# JavaSE 基础 — Day07 笔记
+
+> **日期**:2026-07-21  
+> **项目**:`c260721`  
+> **作者**:WanJL
+
+---
+
+## 一、构造方法(Constructor)
+
+### 1. 构造方法的引出——为什么需要构造方法?
+
+**文件**:`Demo01.java`
+
+在面向对象编程中,我们创建对象后通常通过 setter 方法为属性赋值。但有些属性(如性别 `gender`)是在对象创建时就已确定的,如果先创建对象再通过 setter 设置,虽然代码没有错误,但不符合现实逻辑。
+
+```java
+// 传统方式:先造人,再取名、设性别
+Person p = new Person();
+p.setName("张三");     // 人出生后取名,符合逻辑
+p.setGender("男");     // 人出生后再设置性别,代码没问题但不合常理
+
+// 需求:在创建人的时候,就要给性别和年龄等属性赋值
+```
+
+> **结论**:需要在创建对象的同时,为某些属性赋予初始值——这就用到了 **构造方法(构造器)**。
+
+---
+
+### 2. 构造方法的格式
+
+**文件**:`Demo01.java`
+
+构造方法是一种特殊的方法,具有以下特点:
+
+| 特点 | 说明 |
+|------|------|
+| **方法名** | 与类名完全一致(大小写也相同) |
+| **返回值类型** | **没有**返回值类型,连 `void` 都没有 |
+| **返回值** | 不能使用 `return` 带回结果,因为直接返回新构造的对象 |
+| **调用方式** | 创建对象时自动调用,**不能手动调用** |
+
+```java
+public class Person {
+    private String name;
+    private int age;
+    private String gender;
+
+    // 构造方法格式:访问权限修饰符 类名() { }
+    public Person() {
+        // 构造方法体
+    }
+}
+```
+
+---
+
+### 3. 默认构造方法
+
+**文件**:`Demo01.java`
+
+- Java 中**所有的类**在创建对象时,都会默认调用一个构造方法
+- 每个类都**默认有一个隐藏的无参构造方法**
+- 当我们**显式定义**了构造方法后,自定义的构造方法会**覆盖**默认隐藏的构造方法
+- 默认构造方法的访问权限修饰符**与类的修饰符相同**(类用 `public`,构造方法也是 `public`)
+
+```java
+// 类默认自带的无参构造方法(隐藏):
+// public Person() { }
+```
+
+> **注意**:如果类的构造方法被设置为 `private`,外部就无法创建该类的对象了。
+
+---
+
+### 4. 无参构造方法——对象创建时执行初始化操作
+
+**文件**:`Person.java`
+
+我们可以在无参构造方法中编写代码,在创建对象时自动执行。
+
+```java
+public class Person {
+    private String name;
+    private int age;
+    private String gender;
+
+    // 无参构造方法:创建对象时自动执行
+    public Person() {
+        System.out.println("这是一个构造方法....我开始造人啦");
+        // 可以在构造方法中直接给属性赋固定值
+        this.gender = "男";
+    }
+
+    // getter/setter 省略...
+}
+```
+
+**测试类(PersonTest.java)**:
+
+```java
+public class PersonTest {
+    public static void main(String[] args) {
+        // 创建对象时,自动调用并执行对应的构造方法
+        Person p = new Person();   // 输出:这是一个构造方法....我开始造人啦
+        System.out.println(p.getGender());  // 输出:男
+    }
+}
+```
+
+---
+
+### 5. 构造方法的重载(Overload)
+
+**文件**:`Person.java`
+
+构造方法可以像普通方法一样定义参数,**多个同名构造方法只要参数列表不同(参数类型不同或参数个数不同)**,就称为 **构造方法重载**。
+
+> 注意:如果参数类型相同、个数相同,仅参数名不同,不算重载。
+
+```java
+public class Person {
+    private String name;
+    private int age;
+    private String gender;
+
+    // ① 无参构造方法
+    public Person() {
+        System.out.println("这是一个构造方法....我开始造人啦");
+        this.gender = "男";
+    }
+
+    // ② 单参数构造方法:仅设置性别
+    public Person(String gender) {
+        this.gender = gender;
+    }
+
+    // ③ 双参数构造方法:设置姓名和性别
+    public Person(String name, String gender) {
+        this.name = name;
+        this.gender = gender;
+    }
+
+    // ④ 三参数构造方法:设置姓名、年龄、性别
+    public Person(String name, int age, String gender) {
+        this.name = name;
+        this.age = age;
+        this.gender = gender;
+    }
+}
+```
+
+---
+
+### 6. 有参构造方法的调用
+
+**文件**:`PersonTest.java`, `StudentTest.java`
+
+创建对象时,根据传入的参数列表自动匹配对应的构造方法。
+
+```java
+public class PersonTest {
+    public static void main(String[] args) {
+        // 调用无参构造方法
+        Person p = new Person();
+        System.out.println(p.getGender());  // 输出:男(在无参构造中写死的)
+
+        // 直接输出对象,得到地址
+        System.out.println(p);              // course.Person@地址
+        System.out.println(new Person());   // course.Person@地址
+
+        // 调用有参构造方法:传入性别
+        Person p1 = new Person("女");
+        System.out.println(p1.getGender()); // 输出:女
+    }
+}
+```
+
+```java
+public class StudentTest {
+    public static void main(String[] args) {
+        // 调用三参构造方法创建 Student 对象
+        Student s = new Student("张三", 25, "男");
+    }
+}
+```
+
+---
+
+### 7. 构造方法的核心要点总结
+
+| 序号 | 要点 | 说明 |
+|------|------|------|
+| 1 | **方法名必须与类名一致** | 大小写也必须相同 |
+| 2 | **没有返回值类型** | 连 `void` 都不写 |
+| 3 | **不能 `return` 返回值** | 直接返回新创建的对象 |
+| 4 | **创建对象时自动调用** | 每创建一个对象,执行一次构造方法 |
+| 5 | **不能手动调用** | 构造方法只能通过 `new` 关键字自动触发 |
+| 6 | **默认构造方法** | 每个类默认有一个隐藏的无参构造方法 |
+| 7 | **定义后覆盖默认** | 显式定义构造方法后,默认的会被覆盖 |
+| 8 | **可重载** | 参数列表不同即可定义多个构造方法 |
+| 9 | **权限修饰符与类一致** | 默认构造方法的权限与类的修饰符相同 |
+| 10 | **`private` 构造方法** | 可阻止外部创建对象 |
+
+---
+
+### 8. 完整示例:Person 类 + 4 种构造方法
+
+**文件**:`Person.java`
+
+完整的 `Person` 类包含 3 个私有属性和 4 个重载的构造方法:
+
+```java
+package course;
+
+public class Person {
+    private String name;
+    private int age;
+    private String gender;
+
+    // 构造方法 —— 4 种重载形式
+    public Person() {                              // 无参
+        System.out.println("这是一个构造方法....我开始造人啦");
+        this.gender = "男";
+    }
+    public Person(String gender) {                 // 1 参:性别
+        this.gender = gender;
+    }
+    public Person(String name, String gender) {    // 2 参:姓名 + 性别
+        this.name = name;
+        this.gender = gender;
+    }
+    public Person(String name, int age, String gender) {  // 3 参:姓名 + 年龄 + 性别
+        this.name = name;
+        this.age = age;
+        this.gender = gender;
+    }
+
+    // getter / setter
+    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; }
+    public String getGender() { return gender; }
+    public void setGender(String gender) { this.gender = gender; }
+}
+```
+
+---
+
+### 9. private 构造方法——禁止外部创建对象
+
+**文件**:`Student.java`
+
+如果将构造方法用 `private` 修饰,外部就无法创建该类的对象。这在设计模式中的 **单例模式** 中会用到。
+
+```java
+public class Student {
+    // 私有构造方法:外部无法使用 new Student() 来创建对象
+    /*
+    private Student() {
+        System.out.println("构造学生对象....");
+    }
+    */
+
+    private String name;
+    private int age;
+    private String gender;
+
+    // 公开的无参构造方法(注释掉私有构造后使用)
+    public Student() {
+    }
+
+    // 有参构造方法
+    public Student(String name, int age, String gender) {
+        this.name = name;
+        this.age = age;
+        this.gender = gender;
+    }
+}
+```
+
+---
+
+## 二、课后作业回顾
+
+### 1. 题目 8:Fisher-Yates 洗牌算法(数组随机打乱)
+
+**文件**:`homework/c260717/Demo_08.java`
+
+使用 **Fisher-Yates 洗牌算法** 实现数组元素的随机打乱。核心思路:从后往前遍历,每次将当前元素与随机位置的元素交换。
+
+```java
+package homework.c260717;
+
+import java.util.Arrays;
+import java.util.Random;
+
+public class Demo_08 {
+    public static void shuffleArray(int[] arr) {
+        Random ran = new Random();
+        // Fisher-Yates 洗牌:从后往前遍历
+        for (int i = arr.length - 1; i > 1; i--) {
+            int j = ran.nextInt(i + 1);  // 生成 [0, i] 的随机索引
+            int t = arr[i];
+            arr[i] = arr[j];
+            arr[j] = t;                  // 交换 arr[i] 和 arr[j]
+        }
+    }
+
+    public static void main(String[] args) {
+        int[] arr = {1, 2, 3, 4, 5, 6, 7};
+        System.out.println("打乱前:" + Arrays.toString(arr));
+        shuffleArray(arr);
+        System.out.println("打乱后:" + Arrays.toString(arr));
+    }
+}
+```
+
+> **知识点**:`Random.nextInt(n)` 生成 `[0, n)` 范围的随机整数;Fisher-Yates 算法确保每个排列等概率出现。
+
+---
+
+### 2. Emp 员工类——封装与 setter 校验
+
+**文件**:`homework/c260720/Emp.java`
+
+```java
+package homework.c260720;
+
+public class Emp {
+    private String id;
+    private String name;
+    private double salary;
+
+    // getter/setter —— salary 的 setter 加入校验
+    public void setSalary(double salary) {
+        if (salary < 0) {
+            System.out.println("薪资不能为负数");
+        } else {
+            this.salary = salary;
+        }
+    }
+
+    public void work() {
+        System.out.println("工号" + id + "的员工" + name + "正在工作......");
+    }
+}
+```
+
+**测试类(EmpTest.java)**:
+
+```java
+public class EmpTest {
+    public static void main(String[] args) {
+        Emp emp = new Emp();
+        emp.setId("a1001");
+        emp.setName("张三");
+        emp.setSalary(-10000);  // 输出:薪资不能为负数
+        emp.work();             // 输出:工号a1001的员工张三正在工作......
+    }
+}
+```
+
+---
+
+### 3. MathTools 工具类——回文数判断
+
+**文件**:`homework/c260720/MathTools.java`
+
+回文数判断算法:通过循环逐位取余、反序拼接,最后比较反序结果与原数是否相等。
+
+```java
+public class MathTools {
+    /**
+     * 判断一个整数是否为回文数(正着读反着读一样)
+     */
+    public boolean isPalindrome(int num) {
+        int a = num;       // 保留原始值
+        int sum = 0;
+        while (num > 0) {
+            int b = num % 10;     // 获取最后一位
+            sum = sum * 10 + b;   // 拼接到反序结果
+            num /= 10;            // 缩小 10 倍
+        }
+        return sum == a;          // 比较反序结果与原值
+    }
+}
+```
+
+> **测试用例**:`12321` → `true`(回文),`12345` → `false`,`1221` → `true`
+
+---
+
+### 4. Student 学生类(homework 版)——封装 + 信息展示
+
+**文件**:`homework/c260720/Student.java`
+
+```java
+public class Student {
+    private String name;
+    private int age;
+    private String className;
+
+    // getter/setter 省略...
+
+    public void showInfo() {
+        System.out.println("姓名:" + this.name);
+        System.out.println("年龄:" + this.age);
+        System.out.println("班级:" + this.className);
+    }
+
+    public void study(String course) {
+        System.out.println(this.name + "正在学习" + course);
+    }
+}
+```
+
+**测试类(StudentTest.java)**:
+
+```java
+public class StudentTest {
+    public static void main(String[] args) {
+        Student s = new Student();
+        s.setName("张三");
+        s.setAge(25);
+        s.setClassName("J260713");
+        s.showInfo();
+        s.study("Java");
+    }
+}
+```
+
+---
+
+## 三、随堂练习
+
+> 以下练习基于本日所学构造方法知识点,请在 `Demo01.java`、`Person.java` 等参考代码基础上完成。
+
+### 练习 1:为 Person 类扩充构造方法
+
+基于已有的 `Person` 类,添加以下构造方法:
+- 无参构造:输出"Person 对象创建"
+- 单参构造:只传入年龄(`int age`),将年龄赋值给成员变量
+- 双参构造:传入姓名和年龄
+- 测试类中分别调用 3 种构造方法创建对象
+
+### 练习 2:构造方法权限验证
+
+参照 `Student.java` 中的 `private` 构造方法示例:
+1. 创建一个 `Dog` 类,将无参构造设为 `private`
+2. 在测试类中尝试 `new Dog()`,观察编译错误
+3. 增加一个 `public` 的有参构造方法,测试是否能正常创建对象
+
+### 练习 3:图书类(Book)构造方法设计
+
+创建 `Book` 类,包含:
+- **属性**:书名(`title`,私有)、作者(`author`,私有)、价格(`price`,私有)
+- **构造方法**:
+  - 无参构造
+  - 全参构造(3 个参数)
+- **方法**:`showInfo()` 输出图书信息
+- **测试类**:分别使用无参构造 + setter 赋值,以及全参构造直接赋值两种方式创建图书对象
+
+### 练习 4:构造方法重载练习
+
+创建 `Calculator` 类:
+- **属性**:操作数1(`num1`)、操作数2(`num2`)
+- **构造方法**:
+  - 无参构造(num1=0, num2=0)
+  - 单参构造(num1=参数, num2=0)
+  - 双参构造(num1+num2)
+- **方法**:`add()` 返回两数之和、`show()` 输出两个操作数
+
+### 练习 5:补全 MathTools 工具类
+
+补全 `MathTools` 类中未实现的方法:
+- `printPrime()`:输出 1~100 之间的所有质数,每行 5 个
+- `printSum(int n, int m)`:计算并输出 n~m 之间所有整数的累加和
+- `getLuckyNumber()`:使用 Random 生成 1~100 之间的幸运数字并返回
+
+### 练习 6:补全 SortUtils 冒泡排序
+
+补全 `SortUtils` 类中的 `bubbleSort(int[] arr)` 方法,实现冒泡排序算法。
+
+---
+
+## 四、知识点总结
+
+| 序号 | 知识点 | 说明 | 对应文件 |
+|------|--------|------|---------|
+| 1 | 构造方法概念 | 创建对象时自动调用的特殊方法,用于初始化属性 | `Demo01.java` |
+| 2 | 构造方法格式 | 方法名=类名,无返回值类型(无 void),无 return | `Demo01.java` |
+| 3 | 默认构造方法 | 每个类默认有一个隐藏的无参构造方法,权限与类一致 | `Demo01.java` |
+| 4 | 构造方法覆盖 | 显式定义构造方法后,默认构造方法被覆盖 | `Demo01.java` |
+| 5 | 无参构造方法 | 无参数的构造方法,可执行初始化代码 | `Person.java` |
+| 6 | 有参构造方法 | 可带参数的构造方法,通过参数为属性赋值 | `Person.java` |
+| 7 | 构造方法重载 | 参数列表不同的多个同名构造方法 | `Person.java` |
+| 8 | `this` 在构造方法中 | 区分同名的参数和成员变量 | `Person.java` |
+| 9 | 构造方法调用 | 通过 `new 类名(参数)` 自动匹配并调用 | `PersonTest.java`, `StudentTest.java` |
+| 10 | `private` 构造方法 | 私有构造方法阻止外部创建对象 | `Student.java` |
+| 11 | 输出对象地址 | 直接输出对象引用得到 `包名.类名@哈希码` | `PersonTest.java` |
+| 12 | Fisher-Yates 洗牌 | 数组随机打乱算法(从后往前遍历 + 随机交换) | `homework/c260717/Demo_08.java` |
+| 13 | setter 参数校验 | 在 setter 方法中加入业务规则校验 | `homework/c260720/Emp.java` |
+| 14 | 回文数判断 | 逐位取余反序后与原数比较 | `homework/c260720/MathTools.java` |
+
+---
+
+## 五、拓展阅读
+
+1. **构造方法与普通方法的区别**:构造方法创建对象时自动执行,普通方法需要手动调用;构造方法无返回值,普通方法可以有返回值
+2. **单例模式(Singleton)**:将构造方法私有化,通过静态方法提供唯一实例,是设计模式中的经典模式
+3. **`this()` 构造方法间调用**:在一个构造方法中使用 `this(参数)` 调用另一个构造方法,必须写在第一行
+4. **`super()` 与父类构造方法**:子类构造方法中默认调用父类无参构造 `super()`,后续在继承中会深入学习
+5. **对象初始化顺序**:静态代码块 → 构造代码块 → 构造方法,后续逐渐深入