1. 程式人生 > 實用技巧 >Java進階基礎:繼承的實現,方法重寫注意事項,方法過載與重寫的區別,抽象類,程式碼塊

Java進階基礎:繼承的實現,方法重寫注意事項,方法過載與重寫的區別,抽象類,程式碼塊

1. 繼承

1.1 繼承的實現(掌握)

  • 繼承的概念

    • 繼承是面向物件三大特徵之一,可以使得子類具有父類的屬性和方法,還可以在子類中重新定義,以及追加屬性和方法

  • 實現繼承的格式

    • 繼承通過extends實現

    • 格式:class 子類 extends 父類 { }

      • 舉例:class Dog extends Animal { }

  • 繼承帶來的好處

    • 繼承可以讓類與類之間產生關係,子父類關係,產生子父類後,子類則可以使用父類中非私有的成員。

  • 示例程式碼

    public class Fu {
    public void show() {
    System.out.println("show方法被呼叫");
    }
    }
    public class Zi extends Fu {
    public void method() {
    System.out.println("method方法被呼叫");
    }
    }
    public class Demo {
    public static void main(String[] args) {
    //建立物件,呼叫方法
    Fu f = new Fu();
    f.show();

    Zi z = new Zi();
    z.method();
    z.show();
    }
    }

1.2 繼承的好處和弊端(理解)

  • 繼承好處

    • 提高了程式碼的複用性(多個類相同的成員可以放到同一個類中)

    • 提高了程式碼的維護性(如果方法的程式碼需要修改,修改一處即可)

  • 繼承弊端

    • 繼承讓類與類之間產生了關係,類的耦合性增強了,當父類發生變化時子類實現也不得不跟著變化,削弱了子類的獨立性

  • 繼承的應用場景:

    • 使用繼承,需要考慮類與類之間是否存在is..a的關係,不能盲目使用繼承

      • is..a的關係:誰是誰的一種,例如:老師和學生是人的一種,那人就是父類,學生和老師就是子類

1.3. Java中繼承的特點(掌握)

  • Java中繼承的特點

    1. Java中類只支援單繼承,不支援多繼承

      • 錯誤範例:class A extends B, C { }

    2. Java中類支援多層繼承

  • 多層繼承示例程式碼:

    public class Granddad {

    public void drink() {
    System.out.println("爺爺愛喝酒");
    }

    }

    public class Father extends Granddad {

    public void smoke() {
    System.out.println("爸爸愛抽菸");
    }

    }

    public class Mother {

    public void dance() {
    System.out.println("媽媽愛跳舞");
    }

    }
    public class Son extends Father {
    // 此時,Son類中就同時擁有drink方法以及smoke方法
    }

2. 繼承中的成員訪問特點

2.1 繼承中變數的訪問特點(掌握)

在子類方法中訪問一個變數,採用的是就近原則。

  1. 子類區域性範圍找

  2. 子類成員範圍找

  3. 父類成員範圍找

  4. 如果都沒有就報錯(不考慮父親的父親…)

  • 示例程式碼

    class Fu {
    int num = 10;
    }
    class Zi {
    int num = 20;
    public void show(){
    int num = 30;
    System.out.println(num);
    }
    }
    public class Demo1 {
    public static void main(String[] args) {
    Zi z = new Zi();
    z.show(); // 輸出show方法中的區域性變數30
    }
    }

2.2 super(掌握)

  • this&super關鍵字:

    • this:代表本類物件的引用

    • super:代表父類儲存空間的標識(可以理解為父類物件引用)

  • this和super的使用分別

    • 成員變數:

      • this.成員變數 - 訪問本類成員變數

      • super.成員變數 - 訪問父類成員變數

    • 成員方法:

      • this.成員方法 - 訪問本類成員方法

      • super.成員方法 - 訪問父類成員方法

  • 構造方法:

    • this(…) - 訪問本類構造方法

    • super(…) - 訪問父類構造方法

2.3 繼承中構造方法的訪問特點(理解)

注意:子類中所有的構造方法預設都會訪問父類中無參的構造方法

子類會繼承父類中的資料,可能還會使用父類的資料。所以,子類初始化之前,一定要先完成父類資料的初始化,原因在於,每一個子類構造方法的第一條語句預設都是:super()

問題:如果父類中沒有無參構造方法,只有帶參構造方法,該怎麼辦呢?

1. 通過使用super關鍵字去顯示的呼叫父類的帶參構造方法
2. 子類通過this去呼叫本類的其他構造方法,本類其他構造方法再通過super去手動呼叫父類的帶參的構造方法

注意: this(…)super(…) 必須放在構造方法的第一行有效語句,並且二者不能共存

2.4 繼承中成員方法的訪問特點(掌握)

通過子類物件訪問一個方法

  1. 子類成員範圍找

  2. 父類成員範圍找

  3. 如果都沒有就報錯(不考慮父親的父親…)

2.5 super記憶體圖(理解)

  • 物件在堆記憶體中,會單獨存在一塊super區域,用來存放父類的資料

2.6 方法重寫(掌握)

  • 1、方法重寫概念

    • 子類出現了和父類中一模一樣的方法宣告(方法名一樣,引數列表也必須一樣)

  • 2、方法重寫的應用場景

    • 當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容

  • 3、Override註解

    • 用來檢測當前的方法,是否是重寫的方法,起到【校驗】的作用

2.7 方法重寫的注意事項(掌握)

  • 方法重寫的注意事項

  1. 私有方法不能被重寫(父類私有成員子類是不能繼承的)

  2. 子類方法訪問許可權不能更低(public > 預設 > 私有)

  3. 靜態方法不能被重寫,如果子類也有相同的方法,並不是重寫的父類的方法

  • 示例程式碼

public class Fu {
private void show() {
System.out.println("Fu中show()方法被呼叫");
}

void method() {
System.out.println("Fu中method()方法被呼叫");
}
}

public class Zi extends Fu {

/* 編譯【出錯】,子類不能重寫父類私有的方法*/
@Override
private void show() {
System.out.println("Zi中show()方法被呼叫");
}

/* 編譯【出錯】,子類重寫父類方法的時候,訪問許可權需要大於等於父類 */
@Override
private void method() {
System.out.println("Zi中method()方法被呼叫");
}

/* 編譯【通過】,子類重寫父類方法的時候,訪問許可權需要大於等於父類 */
@Override
public void method() {
System.out.println("Zi中method()方法被呼叫");
}
}

2.8 許可權修飾符 (理解)

2.9 黑馬資訊管理系統使用繼承改進 (掌握)

  • 需求

    把學生類和老師類共性的內容向上抽取,抽取到出一個 Person 父類,讓學生類和老師類繼承 Person 類

  • 實現步驟

    1. 抽取Person類

    2. 優化StudentController類中,inputStudentInfo方法,將setXxx賦值方式,改進為構造方法初始化

      注意:直接修改這種操作方式,不符合我們開發中的一個原則

      開閉原則 ( 對擴充套件開放對修改關閉 ) : 儘量在不更改原有程式碼的前提下以完成需求

      解決:重新建立一個OtherStudentController類

      編寫新的inputStudentInfo方法

    3. 根據StudentController類、OtherStudentController類,向上抽取出BaseStudentController類 再讓StudentController類、OtherStudentController類,繼承BaseStudentController類

  • 程式碼實現

    Person類及學生類和老師類

    public class Person {
    private String id;
    private String name;
    private String age;
    private String birthday;

    public Person() {
    }

    public Person(String id, String name, String age, String birthday) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.birthday = birthday;
    }

    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 String getAge() {
    return age;
    }

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

    public String getBirthday() {
    return birthday;
    }

    public void setBirthday(String birthday) {
    this.birthday = birthday;
    }
    }
    // Student類
    public class Student extends Person {
    public Student() {
    }

    public Student(String id, String name, String age, String birthday) {
    super(id, name, age, birthday);
    }
    }
    // Teacher類
    public class Teacher extends Person {
    public Teacher() {
    }

    public Teacher(String id, String name, String age, String birthday) {
    super(id, name, age, birthday);
    }
    }

    BaseStudentController類

    public abstract class BaseStudentController {
    // 業務員物件
    private StudentService studentService = new StudentService();

    private Scanner sc = new Scanner(System.in);

    // 開啟學生管理系統, 並展示學生管理系統選單
    public void start() {
    //Scanner sc = new Scanner(System.in);
    studentLoop:
    while (true) {
    System.out.println("--------歡迎來到 <學生> 管理系統--------");
    System.out.println("請輸入您的選擇: 1.新增學生 2.刪除學生 3.修改學生 4.檢視學生 5.退出");
    String choice = sc.next();
    switch (choice) {
    case "1":
    // System.out.println("新增");
    addStudent();
    break;
    case "2":
    // System.out.println("刪除");
    deleteStudentById();
    break;
    case "3":
    // System.out.println("修改");
    updateStudent();
    break;
    case "4":
    // System.out.println("查詢");
    findAllStudent();
    break;
    case "5":
    System.out.println("感謝您使用學生管理系統, 再見!");
    break studentLoop;
    default:
    System.out.println("您的輸入有誤, 請重新輸入");
    break;
    }
    }
    }

    // 修改學生方法
    public void updateStudent() {
    String updateId = inputStudentId();
    Student newStu = inputStudentInfo(updateId);
    studentService.updateStudent(updateId, newStu);

    System.out.println("修改成功!");
    }

    // 刪除學生方法
    public void deleteStudentById() {
    String delId = inputStudentId();
    // 3. 呼叫業務員中的deleteStudentById根據id, 刪除學生
    studentService.deleteStudentById(delId);
    // 4. 提示刪除成功
    System.out.println("刪除成功!");
    }

    // 檢視學生方法
    public void findAllStudent() {
    // 1. 呼叫業務員中的獲取方法, 得到學生的物件陣列
    Student[] stus = studentService.findAllStudent();
    // 2. 判斷陣列的記憶體地址, 是否為null
    if (stus == null) {
    System.out.println("查無資訊, 請新增後重試");
    return;
    }
    // 3. 遍歷陣列, 獲取學生資訊並列印在控制檯
    System.out.println("學號\t\t姓名\t年齡\t生日");
    for (int i = 0; i < stus.length; i++) {
    Student stu = stus[i];
    if (stu != null) {
    System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
    }
    }
    }

    // 新增學生方法
    public void addStudent() {
    // StudentService studentService = new StudentService();
    // 1. 鍵盤接收學生資訊
    String id;
    while (true) {
    System.out.println("請輸入學生id:");
    id = sc.next();
    boolean flag = studentService.isExists(id);
    if (flag) {
    System.out.println("學號已被佔用, 請重新輸入");
    } else {
    break;
    }
    }

    Student stu = inputStudentInfo(id);

    // 3. 將學生物件,傳遞給StudentService(業務員)中的addStudent方法
    boolean result = studentService.addStudent(stu);
    // 4. 根據返回的boolean型別結果, 在控制檯列印成功\失敗
    if (result) {
    System.out.println("新增成功");
    } else {
    System.out.println("新增失敗");
    }
    }

    // 鍵盤錄入學生id
    public String inputStudentId() {
    String id;
    while (true) {
    System.out.println("請輸入學生id:");
    id = sc.next();
    boolean exists = studentService.isExists(id);
    if (!exists) {
    System.out.println("您輸入的id不存在, 請重新輸入:");
    } else {
    break;
    }
    }
    return id;
    }

    // 鍵盤錄入學生資訊
    // 開閉原則: 對擴充套件內容開放, 對修改內容關閉
    public Student inputStudentInfo(String id){
    return null;
    }
    }

    StudentController類

    public class StudentController extends BaseStudentController {

    private Scanner sc = new Scanner(System.in);

    // 鍵盤錄入學生資訊
    // 開閉原則: 對擴充套件內容開放, 對修改內容關閉
    @Override
    public Student inputStudentInfo(String id) {
    System.out.println("請輸入學生姓名:");
    String name = sc.next();
    System.out.println("請輸入學生年齡:");
    String age = sc.next();
    System.out.println("請輸入學生生日:");
    String birthday = sc.next();
    Student stu = new Student();
    stu.setId(id);
    stu.setName(name);
    stu.setAge(age);
    stu.setBirthday(birthday);
    return stu;
    }
    }

    OtherStudentController類

    public class OtherStudentController extends BaseStudentController {

    private Scanner sc = new Scanner(System.in);

    // 鍵盤錄入學生資訊
    // 開閉原則: 對擴充套件內容開放, 對修改內容關閉
    @Override
    public Student inputStudentInfo(String id) {
    System.out.println("請輸入學生姓名:");
    String name = sc.next();
    System.out.println("請輸入學生年齡:");
    String age = sc.next();
    System.out.println("請輸入學生生日:");
    String birthday = sc.next();
    Student stu = new Student(id,name,age,birthday);
    return stu;
    }
    }

3.抽象類

3.1抽象類的概述(理解)

當我們在做子類共性功能抽取時,有些方法在父類中並沒有具體的體現,這個時候就需要抽象類了!

在Java中,一個沒有方法體的方法應該定義為抽象方法,而類中如果有抽象方法,該類必須定義為抽象類!

3.2抽象類的特點(記憶)

  • 抽象類和抽象方法必須使用 abstract 關鍵字修飾

    //抽象類的定義
    public abstract class 類名 {}

    //抽象方法的定義
    public abstract void eat();
  • 抽象類中不一定有抽象方法,有抽象方法的類一定是抽象類

  • 抽象類不能例項化

  • 抽象類可以有構造方法

  • 抽象類的子類

    要麼重寫抽象類中的所有抽象方法

    要麼是抽象類

3.3抽象類的案例(應用)

  • 案例需求

    定義貓類(Cat)和狗類(Dog)

    貓類成員方法:eat(貓吃魚)drink(喝水…)

    狗類成員方法:eat(狗吃肉)drink(喝水…)

  • 實現步驟

    1. 貓類和狗類中存在共性內容,應向上抽取出一個動物類(Animal)

    2. 父類Animal中,無法將 eat 方法具體實現描述清楚,所以定義為抽象方法

    3. 抽象方法需要存活在抽象類中,將Animal定義為抽象類

    4. 讓 Cat 和 Dog 分別繼承 Animal,重寫eat方法

    5. 測試類中建立 Cat 和 Dog 物件,呼叫方法測試

  • 程式碼實現

    • 動物類

    public abstract class Animal {
    public void drink(){
    System.out.println("喝水");
    }

    public Animal(){

    }

    public abstract void eat();
    }
    • 貓類

    public class Cat extends Animal {
    @Override
    public void eat() {
    System.out.println("貓吃魚");
    }
    }
    • 狗類

    public class Dog extends Animal {
    @Override
    public void eat() {
    System.out.println("狗吃肉");
    }
    }
    • 測試類

    public static void main(String[] args) {
    Dog d = new Dog();
    d.eat();
    d.drink();

    Cat c = new Cat();
    c.drink();
    c.eat();

    //Animal a = new Animal();
    //a.eat();
    }

3.4模板設計模式

  • 設計模式

    設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。 使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性、程式的重用性。

  • 模板設計模式

    把抽象類整體就可以看做成一個模板,模板中不能決定的東西定義成抽象方法 讓使用模板的類(繼承抽象類的類)去重寫抽象方法實現需求

  • 模板設計模式的優勢

    模板已經定義了通用結構,使用者只需要關心自己需要實現的功能即可

  • 示例程式碼

    模板類

    /*
    作文模板類
    */
    public abstract class CompositionTemplate {

    public final void write(){
    System.out.println("<<我的爸爸>>");

    body();

    System.out.println("啊~ 這就是我的爸爸");

    }

    public abstract void body();
    }

    實現類A

    public class Tom extends CompositionTemplate {

    @Override
    public void body() {
    System.out.println("那是一個秋天, 風兒那麼纏綿,記憶中, " +
    "那天爸爸騎車接我放學回家,我的腳卡在了自行車鏈當中, 爸爸蹬不動,他就站起來蹬...");
    }
    }

    實現類B

    public class Tony extends CompositionTemplate {
    @Override
    public void body() {

    }

    /*public void write(){

    }*/
    }

    測試類

    public class Test {
    public static void main(String[] args) {
    Tom t = new Tom();
    t.write();
    }
    }

3.5final(應用)

  • fianl關鍵字的作用

    • final代表最終的意思,可以修飾成員方法,成員變數,類

  • final修飾類、方法、變數的效果

    • fianl修飾類:該類不能被繼承(不能有子類,但是可以有父類)

    • final修飾方法:該方法不能被重寫

    • final修飾變數:表明該變數是一個常量,不能再次賦值

      • 變數是基本型別,不能改變的是值

      • 變數是引用型別,不能改變的是地址值,但地址裡面的內容是可以改變的

      • 舉例

        public static void main(String[] args){
        final Student s = new Student(23);
        s = new Student(24); // 錯誤
        s.setAge(24); // 正確
        }

3.6黑馬資訊管理系統使用抽象類改進 (應用)

  • 需求

    1. 使用抽象類的思想,將BaseStudentController 中的 inputStudentInfo 方法,定義為抽象方法

    2. 將不希望子類重寫的方法,使用 final 進行修飾

  • 程式碼實現

    BaseStudentController類

    public abstract class BaseStudentController {
    // 業務員物件
    private StudentService studentService = new StudentService();

    private Scanner sc = new Scanner(System.in);

    // 開啟學生管理系統, 並展示學生管理系統選單
    public final void start() {
    //Scanner sc = new Scanner(System.in);
    studentLoop:
    while (true) {
    System.out.println("--------歡迎來到 <學生> 管理系統--------");
    System.out.println("請輸入您的選擇: 1.新增學生 2.刪除學生 3.修改學生 4.檢視學生 5.退出");
    String choice = sc.next();
    switch (choice) {
    case "1":
    // System.out.println("新增");
    addStudent();
    break;
    case "2":
    // System.out.println("刪除");
    deleteStudentById();
    break;
    case "3":
    // System.out.println("修改");
    updateStudent();
    break;
    case "4":
    // System.out.println("查詢");
    findAllStudent();
    break;
    case "5":
    System.out.println("感謝您使用學生管理系統, 再見!");
    break studentLoop;
    default:
    System.out.println("您的輸入有誤, 請重新輸入");
    break;
    }
    }
    }

    // 修改學生方法
    public final void updateStudent() {
    String updateId = inputStudentId();
    Student newStu = inputStudentInfo(updateId);
    studentService.updateStudent(updateId, newStu);

    System.out.println("修改成功!");
    }

    // 刪除學生方法
    public final void deleteStudentById() {
    String delId = inputStudentId();
    // 3. 呼叫業務員中的deleteStudentById根據id, 刪除學生
    studentService.deleteStudentById(delId);
    // 4. 提示刪除成功
    System.out.println("刪除成功!");
    }

    // 檢視學生方法
    public final void findAllStudent() {
    // 1. 呼叫業務員中的獲取方法, 得到學生的物件陣列
    Student[] stus = studentService.findAllStudent();
    // 2. 判斷陣列的記憶體地址, 是否為null
    if (stus == null) {
    System.out.println("查無資訊, 請新增後重試");
    return;
    }
    // 3. 遍歷陣列, 獲取學生資訊並列印在控制檯
    System.out.println("學號\t\t姓名\t年齡\t生日");
    for (int i = 0; i < stus.length; i++) {
    Student stu = stus[i];
    if (stu != null) {
    System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
    }
    }
    }

    // 新增學生方法
    public final void addStudent() {
    // StudentService studentService = new StudentService();
    // 1. 鍵盤接收學生資訊
    String id;
    while (true) {
    System.out.println("請輸入學生id:");
    id = sc.next();
    boolean flag = studentService.isExists(id);
    if (flag) {
    System.out.println("學號已被佔用, 請重新輸入");
    } else {
    break;
    }
    }

    Student stu = inputStudentInfo(id);

    // 3. 將學生物件,傳遞給StudentService(業務員)中的addStudent方法
    boolean result = studentService.addStudent(stu);
    // 4. 根據返回的boolean型別結果, 在控制檯列印成功\失敗
    if (result) {
    System.out.println("新增成功");
    } else {
    System.out.println("新增失敗");
    }
    }

    // 鍵盤錄入學生id
    public String inputStudentId() {
    String id;
    while (true) {
    System.out.println("請輸入學生id:");
    id = sc.next();
    boolean exists = studentService.isExists(id);
    if (!exists) {
    System.out.println("您輸入的id不存在, 請重新輸入:");
    } else {
    break;
    }
    }
    return id;
    }

    // 鍵盤錄入學生資訊
    // 開閉原則: 對擴充套件內容開放, 對修改內容關閉
    public abstract Student inputStudentInfo(String id);
    }

4.程式碼塊

4.1程式碼塊概述 (理解)

在Java中,使用 { } 括起來的程式碼被稱為程式碼塊

4.2程式碼塊分類 (理解)

  • 區域性程式碼塊

    • 位置: 方法中定義

    • 作用: 限定變數的生命週期,及早釋放,提高記憶體利用率

    • 示例程式碼

      public class Test {
      /*
      區域性程式碼塊
      位置:方法中定義
      作用:限定變數的生命週期,及早釋放,提高記憶體利用率
      */
      public static void main(String[] args) {
      {
      int a = 10;
      System.out.println(a);
      }

      // System.out.println(a);
      }
      }
  • 構造程式碼塊

    • 位置: 類中方法外定義

    • 特點: 每次構造方法執行的時,都會執行該程式碼塊中的程式碼,並且在構造方法執行前執行

    • 作用: 將多個構造方法中相同的程式碼,抽取到構造程式碼塊中,提高程式碼的複用性

    • 示例程式碼

      public class Test {
      /*
      構造程式碼塊:
      位置:類中方法外定義
      特點:每次構造方法執行的時,都會執行該程式碼塊中的程式碼,並且在構造方法執行前執行
      作用:將多個構造方法中相同的程式碼,抽取到構造程式碼塊中,提高程式碼的複用性
      */
      public static void main(String[] args) {
      Student stu1 = new Student();
      Student stu2 = new Student(10);
      }
      }

      class Student {

      {
      System.out.println("好好學習");
      }

      public Student(){
      System.out.println("空引數構造方法");
      }

      public Student(int a){
      System.out.println("帶引數構造方法...........");
      }
      }
  • 靜態程式碼塊

    • 位置: 類中方法外定義

    • 特點: 需要通過static關鍵字修飾,隨著類的載入而載入,並且只執行一次

    • 作用: 在類載入的時候做一些資料初始化的操作

    • 示例程式碼

      public class Test {
      /*
      靜態程式碼塊:
      位置:類中方法外定義
      特點:需要通過static關鍵字修飾,隨著類的載入而載入,並且只執行一次
      作用:在類載入的時候做一些資料初始化的操作
      */
      public static void main(String[] args) {
      Person p1 = new Person();
      Person p2 = new Person(10);
      }
      }

      class Person {
      static {
      System.out.println("我是靜態程式碼塊, 我執行了");
      }

      public Person(){
      System.out.println("我是Person類的空引數構造方法");
      }

      public Person(int a){
      System.out.println("我是Person類的帶...........引數構造方法");
      }
      }

4.3黑馬資訊管理系統使用程式碼塊改進 (應用)

  • 需求

    使用靜態程式碼塊,初始化一些學生資料

  • 實現步驟

    1. 在StudentDao類中定義一個靜態程式碼塊,用來初始化一些學生資料

    2. 將初始化好的學生資料儲存到學生陣列中

  • 示例程式碼

    StudentDao類

    public class StudentDao {
    // 建立學生物件陣列
    private static Student[] stus = new Student[5];

    static {
    Student stu1 = new Student("heima001","張三","23","1999-11-11");
    Student stu2 = new Student("heima002","李四","24","2000-11-11");

    stus[0] = stu1;
    stus[1] = stu2;
    }

    // 新增學生方法
    public boolean addStudent(Student stu) {

    // 2. 新增學生到陣列
    //2.1 定義變數index為-1,假設陣列已經全部存滿,沒有null的元素
    int index = -1;
    //2.2 遍歷陣列取出每一個元素,判斷是否是null
    for (int i = 0; i < stus.length; i++) {
    Student student = stus[i];
    if(student == null){
    index = i;
    //2.3 如果為null,讓index變數記錄當前索引位置,並使用break結束迴圈遍歷
    break;
    }
    }

    // 3. 返回是否新增成功的boolean型別狀態
    if(index == -1){
    // 裝滿了
    return false;
    }else{
    // 沒有裝滿, 正常新增, 返回true
    stus[index] = stu;
    return true;
    }
    }
    // 檢視學生方法
    public Student[] findAllStudent() {
    return stus;
    }

    public void deleteStudentById(String delId) {
    // 1. 查詢id在容器中所在的索引位置
    int index = getIndex(delId);
    // 2. 將該索引位置,使用null元素進行覆蓋
    stus[index] = null;
    }

    public int getIndex(String id){
    int index = -1;
    for (int i = 0; i < stus.length; i++) {
    Student stu = stus[i];
    if(stu != null && stu.getId().equals(id)){
    index = i;
    break;
    }
    }
    return index;
    }

    public void updateStudent(String updateId, Student newStu) {
    // 1. 查詢updateId, 在容器中的索引位置
    int index = getIndex(updateId);
    // 2. 將該索引位置, 使用新的學生物件替換
    stus[index] = newStu;
    }
    }