Browse Source

docs: 更新20260722课堂笔记,同步代码变更——新增方法重写(@Override)、super关键字、同名属性处理、单继承与多层继承、Object根类、访问修饰符继承等内容

WanJL 2 days ago
parent
commit
3ee3a52a9b

+ 2 - 2
README.md

@@ -29,7 +29,7 @@
 | 2026-07-17 | [Java方法4种声明方式(无参无返回值/有参无返回值/有参有返回值/无参有返回值)、方法中调用方法、数组作为方法参数、Random随机数类、Random+方法综合练习、三种排序算法复习、Scanner 学生信息采集系统](./课堂笔记/01-JavaSE基础-笔记/20260717-笔记.md) |
 | 2026-07-20 | [面向对象基础:类与对象、成员变量与成员方法、创建对象与使用成员](./课堂笔记/01-JavaSE基础-笔记/20260720-笔记.md) |
 | 2026-07-21 | [构造方法(构造器):构造方法引出、格式与特点、默认构造方法、无参构造方法、构造方法重载、有参构造方法调用、this 在构造方法中的应用、private 构造方法阻止外部创建对象、完整 Person 示例(4种构造方法重载)、课后作业回顾(Fisher-Yates 洗牌算法/Emp 员工封装/MathTools 回文数/Student 封装展示)](./课堂笔记/01-JavaSE基础-笔记/20260721-笔记.md) |
-| 2026-07-22 | [继承:继承的概念、格式、好处与弊端、is...a 使用场景、多层继承、随堂练习(学生成绩管理系统-构造方法版)、课后作业(猜数游戏面向对象版/BookManager图书管理系统)](./课堂笔记/01-JavaSE基础-笔记/20260722-笔记.md) |
+| 2026-07-22 | [继承:继承的概念、格式、好处与弊端、is...a 使用场景、方法重写(@Override)、super 关键字调用父类成员、同名属性处理(this vs super)、单继承与多层继承、Object 根类、访问修饰符在继承中的体现、随堂练习(学生成绩管理系统-构造方法版)、课后作业(猜数游戏面向对象版/BookManager图书管理系统)](./课堂笔记/01-JavaSE基础-笔记/20260722-笔记.md) |
 
 ## 二、授课代码
 
@@ -45,7 +45,7 @@
 | 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 关键字在构造方法中的应用、随堂练习(Cat/Dog/Book/Phone/单例Manager)、Fisher-Yates 洗牌算法(数组随机打乱)、封装与 setter 校验复习、回文数判断算法 | `c260721` | [`course`](./授课代码/c260721/src/course/) / [`homework/c260717`](./授课代码/c260721/src/homework/c260717/) / [`homework/c260720`](./授课代码/c260721/src/homework/c260720/) / [`exercise/exercise01`](./授课代码/c260721/src/exercise/exercise01/) / [`exercise/exercise02`](./授课代码/c260721/src/exercise/exercise02/) |
-| 2026-07-22 | 继承(extends)的概念、格式、好处与弊端、is...a 使用场景、多层继承(Animal  Bird  Penguin)、随堂练习(学生成绩管理系统-构造方法版/对象数组/冒泡排序)、课后作业(GuessGame 猜数游戏面向对象版/BookManager 图书管理系统) | `c260722` | [`course`](./授课代码/c260722/src/course/) / [`exercise/studentSystem`](./授课代码/c260722/src/exercise/studentSystem/) / [`homework/p08_guessgame`](./授课代码/c260722/src/homework/p08_guessgame/) / [`homework/p09_bookmanager`](./授课代码/c260722/src/homework/p09_bookmanager/) |
+| 2026-07-22 | 继承(extends)的概念、格式、好处与弊端、is...a 使用场景、方法重写(Override)、super 关键字、同名属性处理、单继承与多层继承(Animal→Bird→Penguin / Granddad→Dad→Son、访问修饰符在继承中的体现、随堂练习(学生成绩管理系统-构造方法版/对象数组/冒泡排序)、课后作业(GuessGame 猜数游戏面向对象版/BookManager 图书管理系统) | `c260722` | [`course`](./授课代码/c260722/src/course/) / [`exercise/studentSystem`](./授课代码/c260722/src/exercise/studentSystem/) / [`homework/p08_guessgame`](./授课代码/c260722/src/homework/p08_guessgame/) / [`homework/p09_bookmanager`](./授课代码/c260722/src/homework/p09_bookmanager/) |
 
 ## 三、课堂练习题
 

+ 3 - 1
授课代码/c260722/src/course/Animal.java

@@ -8,7 +8,9 @@ package course;
  * @description 动物类
  * @create 2026/7/22
  */
-public class Animal {
+public class Animal{
+
+
 
     public void eat(){
         System.out.println("吃......");

+ 18 - 0
授课代码/c260722/src/course/Bird.java

@@ -9,6 +9,24 @@ package course;
  * @create 2026/7/22
  */
 public class Bird extends Animal{
+
+    private String s1;  //私有的
+    String s2;  //默认的
+    protected String s3;    //非同包子类的
+    public String s4;   //公共的
+
+
+    /**
+     * 子类重写父类的方法
+     */
+    //@Override   // @Override 是重写注解,可以加也可以不加,如果加了这个注解,注解下面的第一个方法必须是和父类方法同名
+    // 即使不加@Override
+    // 只要子类出现和父类完全同名的方法,也算是子类重写父类的方法
+    // 但是如果方法名不同,那么就算是子类特有的方法。
+    public void eat() {
+        System.out.println("鸟吃自己的.....");
+    }
+
     public void fly(){
         System.out.println("飞.......");
     }

+ 16 - 0
授课代码/c260722/src/course/Dad.java

@@ -0,0 +1,16 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Dad
+ * @description 父亲
+ * @create 2026/7/22
+ */
+public class Dad extends Granddad{
+    public void eat(){
+        super.eat();
+        System.out.println("爸爸爱吃肉....");
+    }
+}

+ 16 - 0
授课代码/c260722/src/course/Demo01.java

@@ -74,6 +74,22 @@ public class Demo01 {
             学生是人的一种,那么 人类是父类 学生类是子类,可以建立继承关系
             Car
             Student  汽车 跟 学生 不产生is...a关系 所以不能建立继承关系
+
+
+            子类可以使用父类的成员(属性变量和方法)
+            但是如果出现父子类有相同的成员,那会怎么办呢?
+
+            如果子类出现和父类相同的方法,那么子类会覆盖(重写)父类的方法。
+            而且默认调用的也是子类的方法,如果要想调用父类被覆盖的方法,需要使用super.父类方法()
+            如果子类出现和父类相同的属性变量,会同时存在。
+            只不过在调用的时候,默认是使用子类自己的属性变量。
+            如果需要调用父类的属性变量,需要使用super.父类变量。
+
+            Java中的继承只支持单继承,不支持多继承。
+            一个子类只能有一个父类。
+            但是Java支持多层继承,也就是 子类的父类可以继承自其他类。
+            也就是是说,Java只能有一个直接父类,但是可以有多个间接父类。
+            Java中所有的类的父类,叫 Object类
      */
 
 

+ 15 - 0
授课代码/c260722/src/course/Granddad.java

@@ -0,0 +1,15 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Granddad
+ * @description
+ * @create 2026/7/22
+ */
+public class Granddad {
+    public void eat(){
+        System.out.println("爷爷爱喝酒....");
+    }
+}

+ 9 - 0
授课代码/c260722/src/course/Penguin.java

@@ -9,4 +9,13 @@ package course;
  * @create 2026/7/22
  */
 public class Penguin extends Bird{
+    String s3;
+    @Override
+    public void fly() {
+        System.out.println("我不飞..我肚皮贴着冰面滑......");
+        System.out.println("调用父类的s2属性"+super.s2);
+        System.out.println("调用自己的s2属性"+this.s2);
+        System.out.println("调用父类的s3属性"+super.s3);//调用父类的s3属性
+        System.out.println("调用自己的s3属性"+this.s3);//调用自己的s3
+    }
 }

+ 16 - 0
授课代码/c260722/src/course/Son.java

@@ -0,0 +1,16 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Son
+ * @description 儿子
+ * @create 2026/7/22
+ */
+public class Son extends Dad{
+    public void eat(){
+        super.eat();//调用自己父类
+        System.out.println("儿子不吃饭....");
+    }
+}

+ 3 - 0
授课代码/c260722/src/course/Test01.java

@@ -20,7 +20,10 @@ public class Test01 {
         bird.sleep();
         bird.fly();
         Penguin p=new Penguin();
+        p.s3="哈哈哈哈";
+        p.s2="s2222222";
         p.eat();
         p.sleep();
+        p.fly();
     }
 }

+ 17 - 0
授课代码/c260722/src/course/Test02.java

@@ -0,0 +1,17 @@
+package course;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Test02
+ * @description
+ * @create 2026/7/22
+ */
+public class Test02 {
+    public static void main(String[] args) {
+        Son s=new Son();
+        s.eat();
+
+    }
+}

+ 257 - 10
课堂笔记/01-JavaSE基础-笔记/20260722-笔记.md

@@ -166,7 +166,243 @@ class Student extends Car { }      // 学生不是汽车的一种 ✗
 
 ---
 
-## 二、随堂练习——学生成绩管理系统(构造方法版)
+### 8. 方法重写(Method Override)
+
+**文件**:`Demo01.java`、`Bird.java`、`Penguin.java`
+
+当子类中出现与父类 **完全相同的方法名、参数列表和返回值类型** 的方法时,称为 **方法重写(Override)**。子类会覆盖父类的方法,默认调用子类的版本。
+
+```java
+// 父类 Animal
+public class Animal {
+    public void eat() {
+        System.out.println("吃......");
+    }
+}
+
+// 子类 Bird —— 重写父类的 eat() 方法
+public class Bird extends Animal {
+    // @Override 是重写注解(可选),加上后编译器会检查该方法是否真的重写了父类方法
+    // 即使不加 @Override,只要方法签名完全一致,也是重写
+    public void eat() {
+        System.out.println("鸟吃自己的.....");
+    }
+}
+
+// 子类 Penguin —— 重写父类 Bird 的 fly() 方法
+public class Penguin extends Bird {
+    @Override   // 推荐加上,便于阅读和检查
+    public void fly() {
+        System.out.println("我不飞..我肚皮贴着冰面滑......");
+    }
+}
+```
+
+**重写 vs 非重写**:
+| 情况 | 结果 |
+|------|------|
+| 子类方法与父类方法 **签名完全一致** | 重写(Override) |
+| 子类方法与父类方法 **方法名不同** | 子类特有的方法,不是重写 |
+
+**测试效果**:
+```java
+// Test01.java
+public class Test01 {
+    public static void main(String[] args) {
+        Animal animal = new Animal();
+        animal.eat();            // 吃......
+
+        Bird bird = new Bird();
+        bird.eat();              // 鸟吃自己的.....(重写后调用子类版本)
+
+        Penguin p = new Penguin();
+        p.fly();                 // 我不飞..我肚皮贴着冰面滑......(重写后调用子类版本)
+    }
+}
+```
+
+> **注意**:重写发生在 **子类和父类之间**,方法签名必须完全一致(方法名 + 参数列表 + 返回值类型)。重写不是必须加 `@Override` 注解,但建议加上,因为它能让编译器帮助检查是否正确重写。
+
+---
+
+### 9. super 关键字
+
+**文件**:`Granddad.java`、`Dad.java`、`Son.java`、`Test02.java`
+
+`super` 关键字用于在子类中 **引用父类的成员**(方法或属性),主要用在以下场景:
+
+| 使用方式 | 说明 |
+|---------|------|
+| `super.父类方法()` | 调用父类中被重写的方法 |
+| `super.父类属性` | 访问父类中与子类同名的属性 |
+
+**示例:多层链式调用 `super.eat()`**
+
+```java
+// Granddad.java —— 爷爷类(顶层父类)
+public class Granddad {
+    public void eat() {
+        System.out.println("爷爷爱喝酒....");
+    }
+}
+
+// Dad.java —— 父亲类(继承 Granddad)
+public class Dad extends Granddad {
+    public void eat() {
+        super.eat();               // 先调用爷爷的 eat()
+        System.out.println("爸爸爱吃肉....");
+    }
+}
+
+// Son.java —— 儿子类(继承 Dad)
+public class Son extends Dad {
+    public void eat() {
+        super.eat();               // 先调用爸爸的 eat()(爸爸内部又会调用爷爷的 eat())
+        System.out.println("儿子不吃饭....");
+    }
+}
+```
+
+**测试效果**:
+```java
+// Test02.java
+public class Test02 {
+    public static void main(String[] args) {
+        Son s = new Son();
+        s.eat();
+    }
+}
+```
+
+**预期输出**:
+```
+爷爷爱喝酒....
+爸爸爱吃肉....
+儿子不吃饭....
+```
+
+> **调用链分析**:`Son.eat()` → `super.eat()` 调用 `Dad.eat()` → `Dad.eat()` 中的 `super.eat()` 调用 `Granddad.eat()` → 输出"爷爷爱喝酒...." → 回到 Dad 输出"爸爸爱吃肉...." → 回到 Son 输出"儿子不吃饭...."。形成了方法的 **链式调用**。
+
+---
+
+### 10. 同名属性的处理
+
+**文件**:`Bird.java`、`Penguin.java`、`Test01.java`
+
+当子类和父类定义了 **同名的成员变量** 时,两个变量会 **同时存在** 于子类对象中。访问规则如下:
+
+| 访问方式 | 访问的是 |
+|---------|---------|
+| `变量名` 或 `this.变量名` | **子类自己** 的属性 |
+| `super.变量名` | **父类** 的属性 |
+
+**示例**:
+```java
+// Bird.java —— 父类中定义了 s2(默认权限)、s3(protected 权限)
+public class Bird extends Animal {
+    String s2;                // 默认权限
+    protected String s3;      // protected 权限
+}
+
+// Penguin.java —— 子类中定义了同名的 s2、s3
+public class Penguin extends Bird {
+    String s3;                // 与父类 Bird 的 s3 同名
+
+    @Override
+    public void fly() {
+        System.out.println("调用父类的s2属性:" + super.s2);   // 访问 Bird 的 s2
+        System.out.println("调用自己的s2属性:" + this.s2);    // 访问 Penguin 的 s2(如果没有则继承 Bird 的)
+        System.out.println("调用父类的s3属性:" + super.s3);   // 访问 Bird 的 s3
+        System.out.println("调用自己的s3属性:" + this.s3);    // 访问 Penguin 的 s3
+    }
+}
+```
+
+**测试效果**:
+```java
+// Test01.java
+Penguin p = new Penguin();
+p.s3 = "哈哈哈哈";      // 设置 Penguin 自己的 s3
+p.s2 = "s2222222";      // 设置 Bird 的 s2(Penguin 没有同名 s2,所以直接继承使用)
+p.fly();
+```
+
+> **总结**:如果子类没有定义同名的属性,`this.属性` 和 `super.属性` 访问的是同一个父类属性。如果子类定义了同名属性,则 `this` 访问自己的,`super` 访问父类的。
+
+---
+
+### 11. Java 继承的限制
+
+**文件**:`Demo01.java`
+
+Java 的继承机制有以下重要限制:
+
+#### ① 单继承(Single Inheritance)
+Java 中一个子类 **只能有一个直接父类**,不支持 C++ 中的多继承。
+
+```java
+// ❌ 错误:Java 不支持多继承
+class C extends A, B {  // 编译报错!
+}
+
+// ✅ 正确:一个子类只能有一个直接父类
+class B extends A {  // 正确
+}
+```
+
+#### ② 多层继承(Multi-level Inheritance)
+Java **支持多层继承**,即一个类的父类可以继承自其他类。
+
+```java
+// ✅ 多层继承:Son → Dad → Granddad
+class Granddad { }
+class Dad extends Granddad { }     // Dad 的直接父类是 Granddad
+class Son extends Dad { }          // Son 的直接父类是 Dad
+                                   // Son 的间接父类是 Granddad
+```
+
+| 概念 | 说明 |
+|------|------|
+| **直接父类** | 子类通过 `extends` 直接继承的类(如 Son 的 Dad) |
+| **间接父类** | 子类的父类的父类……(如 Son 的 Granddad) |
+
+#### ③ Object——所有类的根父类
+
+**文件**:`Demo01.java`
+
+Java 中 **所有的类都默认继承自 `Object` 类**。如果一个类没有显式使用 `extends` 关键字,它也会隐式继承 `Object`。
+
+```java
+// 以下两种写法等价:
+public class Animal { }                // 隐式继承 Object
+public class Animal extends Object { } // 显式继承 Object
+```
+
+`Object` 类中定义了一些所有对象都具备的基本方法(如 `toString()`、`equals()`、`hashCode()` 等)。
+
+---
+
+### 12. 访问修饰符在继承中的体现
+
+**文件**:`Bird.java`
+
+子类能访问的父类成员范围取决于父类成员的访问修饰符:
+
+| 修饰符 | 本类 | 同包子类 | 异包子类 | 所有类 |
+|--------|:----:|:--------:|:--------:|:------:|
+| `private` | ✅ | ❌ | ❌ | ❌ |
+| 默认(缺省) | ✅ | ✅ | ❌ | ❌ |
+| `protected` | ✅ | ✅ | ✅ | ❌ |
+| `public` | ✅ | ✅ | ✅ | ✅ |
+
+```java
+public class Bird extends Animal {
+    private String s1;      // 私有的 —— 仅本类可访问
+    String s2;              // 默认的 —— 同包可访问
+    protected String s3;    // protected —— 同包 + 子类可访问
+    public String s4;       // 公共的 —— 所有类可访问
+}
+```
 
 **包名**:`exercise.studentSystem`
 
@@ -446,22 +682,33 @@ public class BookManagerTest {
 |--------|---------|------|
 | **继承的概念** | ⭐⭐⭐⭐⭐ | Java 三大特征之一,子类 extends 父类 |
 | **继承的格式** | ⭐⭐⭐⭐⭐ | `class 子类 extends 父类 {}` |
-| **继承的好处** | ⭐⭐⭐⭐ | 提高代码复用性和可维护性 |
-| **继承的弊端(耦合性)** | ⭐⭐⭐⭐ | 父类变化影响子类,降低独立性 |
+| **继承的好处与弊端** | ⭐⭐⭐⭐ | 提高复用性但增强耦合性 |
 | **is...a 关系判断** | ⭐⭐⭐⭐ | 使用继承前必须判断是否符合 is...a |
-| **多层继承** | ⭐⭐⭐ | 一个类可继承自另一个已继承的子类 |
+| **方法重写(Override)** | ⭐⭐⭐⭐⭐ | 子类覆盖父类方法,方法签名必须完全一致 |
+| **@Override 注解** | ⭐⭐⭐⭐ | 可选的检查注解,推荐加上帮助编译器校验 |
+| **super 关键字** | ⭐⭐⭐⭐⭐ | `super.方法()` 调用父类方法,`super.属性` 访问父类属性 |
+| **同名属性处理** | ⭐⭐⭐⭐ | 父子类同名属性同时存在,`this` 访问自己的,`super` 访问父类的 |
+| **单继承** | ⭐⭐⭐⭐⭐ | Java 一个子类只能有一个直接父类 |
+| **多层继承** | ⭐⭐⭐⭐ | 支持链式继承(Son → Dad → Granddad) |
+| **Object 根类** | ⭐⭐⭐⭐ | Java 所有类都隐式继承 Object |
+| **访问修饰符在继承中** | ⭐⭐⭐⭐ | `private` 不可继承,`protected` 子类可访问 |
 | **构造方法 + 对象数组 + 冒泡排序综合应用** | ⭐⭐⭐⭐⭐ | 学生管理系统、图书管理系统 |
 
 ### 注意事项
 
-1. **继承是单继承**:Java 中一个类只能有一个直接父类(单继承体系)
-2. **私有成员不可继承**:子类不能使用父类中 `private` 修饰的成员
-3. **构造方法不可继承**:父类的构造方法不会被子类继承,但子类可以通过 `super()` 调用
-4. **继承的耦合性**:合理设计继承层次,避免过深的继承链
+1. **单继承**:Java 中一个类只能有一个直接父类(区别于 C++ 的多继承)
+2. **多层继承 ≠ 多继承**:Java 支持 Son → Dad → Granddad 这样的链式继承,但不支持同时继承多个类
+3. **私有成员不可访问**:子类不能直接使用父类 `private` 修饰的成员
+4. **构造方法不可继承**:父类的构造方法不会被子类继承,子类通过 `super(参数)` 调用父类构造方法
+5. **方法重写 vs 方法重载**:
+   - 重写(Override):父子类之间,方法签名完全一致
+   - 重载(Overload):同一个类中,方法名相同参数列表不同
+6. **`@Override` 注解**:不强制但建议加上,可以帮助编译器检查是否真正重写了父类方法
+7. **继承的耦合性**:合理设计继承层次,避免过深的继承链,优先考虑组合而非继承
 
 ### 拓展阅读
 
-- Java 继承中 `super` 关键字的使用
-- 方法重写(Override)与方法重载(Overload)的区别
 - `final` 关键字对继承的限制(`final` 类不能被继承,`final` 方法不能被重写)
 - 继承与组合(Composition)的对比——优先使用组合而非继承
+- `Object` 类的常见方法:`toString()`、`equals()`、`hashCode()`、`getClass()`
+- 方法重写的规则(访问权限不能更低、返回值类型可以协变、抛出异常不能更宽等)