零基礎 “入坑” Java--- 十、繼承

文章目錄

  • 一、何為繼承
  • 二、繼承語法
  • 三、父類成員訪問
    • 1.成員變量
    • 2.成員方法
  • 四、super關鍵字
  • 五、子類構造方法
  • 六、super和this辨析
  • 七、再談初始化
  • 八、protected關鍵字
  • 九、繼承方式
  • 十、final關鍵字
  • 十一、繼承與組合

根據我們學過的類的知識,我們來定義兩個類:一個貓類,一個狗類:

class Dog {public String name;public int age;public String sex;public void eat() {System.out.println(this.name + "吃飯");}public void sleep() {System.out.println(this.name + "睡覺");}public void wang() {System.out.println(this.name + "汪汪叫");}
}
class Cat {public String name;public int age;public String sex;public void eat() {System.out.println(this.name + "吃飯");}public void sleep() {System.out.println(this.name + "睡覺");}public void miao() {System.out.println(this.name + "喵喵叫");}
}

仔細觀察代碼會發現,兩個類中存在許多共性,代碼就會比較冗余。為了解決這個問題,面向對象思想中提出了繼承的概念,用于對共性進行抽取,實現代碼復用,減少冗余。

一、何為繼承

繼承是面向對象思想中可以實現代碼復用的一種重要手段,它允許程序員在保持原有類(父類/基類/超類) 的基礎上進行擴展,增添新功能,由此產生的新的類,稱為子類/派生類。

繼承主要解決:對共性進行抽取,從而實現代碼的復用。

二、繼承語法

在Java中借助extends關鍵字實現繼承關系,語法格式為:

修飾符 class 子類 extends 父類 {
//語句
}

我們根據語法對貓和狗類的共性進行抽取:

class Animal {public String name;public int age;public String sex;public void eat() {System.out.println(name + "吃飯");}public void sleep() {System.out.println(name + "睡覺");}
}
class Dog extends Animal {public void wang() {System.out.println(name + "汪汪叫");}
}
class Cat extends Animal {public void miao() {System.out.println(name + "喵喵叫");}
}

在繼承時我們需要注意:

1.子類繼承父類之后,會繼承父類中的成員方法和成員變量(靜態成員除外)。
2.子類繼承父類之后,必須有子類獨有的成員,需體現出與父類的不同,否則沒必要繼承。

三、父類成員訪問

1.成員變量

我們可以在子類中直接訪問從父類中繼承下來的成員變量

class Fu {public int a;public int b;
}
class Zi extends Fu {public int c;public void test() {a = 10;b = 20;c = 30;System.out.println(a + " " + b + " " + c + " ");}
}
public class Test2 {public static void main(String[] args) {Zi zi = new Zi();zi.test();}
}

但是當父類和子類的成員變量名相同時,會訪問哪個呢:

class Fu {public int a = 1;
}
class Zi extends Fu {public int a = 0;public void test() {System.out.println(a);}
}
public class Test2 {public static void main(String[] args) {Zi zi = new Zi();zi.test(); //0}
}

由運行結果可知:成員變量的訪問遵循就近原則,如果子類中有,則優先使用子類的成員變量;如果子類中沒有,則使用父類的成員變量;若父類和子類均沒有,則編譯報錯。

2.成員方法

我們可以在子類中直接訪問從父類中繼承下來的成員方法

class Fu {public void test1() {System.out.println("嘻嘻");}
}
class Zi extends Fu {public void test2() {System.out.println("哈哈");}public void test() {test1();test2();}
}
public class Test2 {public static void main(String[] args) {Zi zi = new Zi();zi.test();}
}

但是當父類和子類的成員方法名相同時,會訪問哪個呢:

class Fu {public void test1() {System.out.println("嘻嘻");}public void test2(int x) {System.out.println("xixi");}
}
class Zi extends Fu {public void test1() {System.out.println("哈哈");}public void test2() {System.out.println("haha");}public void test() {test1(); //哈哈test2(); //haha(調用子類)test2(666); //xixi(調用父類)}
}
public class Test2 {public static void main(String[] args) {Zi zi = new Zi();zi.test();}
}

由運行結果可知:成員方法的訪問遵循就近原則,如果子類中有,則優先使用子類的成員方法;當父類和子類的 同名方法的 參數列表不同時,根據調用方法時傳遞的參數,選擇合適的方法;如果子類中沒有,則使用父類的成員方法;若父類和子類均沒有,則編譯報錯。

但是當我們想在子類中訪問父類的 同名的成員時,應該怎么辦呢?此時,就可以使用super關鍵字。

四、super關鍵字

Java中提供了super關鍵字,幫助我們在子類中訪問父類的成員。

class Fu {public int a = 1;public int b = 2;public int c = 3;
}
class Zi extends Fu {public int a = 11;public int d = 4;public void test() {System.out.println(a); //11System.out.println(b); //2System.out.println(c); //3System.out.println(d); //4System.out.println(super.a); //1}
}
public class Test2 {public static void main(String[] args) {Zi zi = new Zi();zi.test();}
}

在這里插入圖片描述
對于super關鍵字:

1.如果super在當前類中被使用,則當前類一定為子類。
2.super只能訪問從父類中繼承過來的成員。
3.使用this訪問,既可以訪問父類成員也可以訪問子類成員,但當訪問父類和子類中同名的成員時,子類成員優先被訪問。

因此,子類test方法中以下寫法均正確:

        System.out.println(this.a); //11System.out.println(this.b); //2System.out.println(this.c); //3System.out.println(this.d); //4System.out.println(super.a); //1System.out.println(super.b); //2System.out.println(super.c); //3

注意:super關鍵字只能在非靜態方法中使用!!!

五、子類構造方法

class Animal {public String name;public int age;public String sex;//一個參數的構造方法public Animal(String name) {this.name = name;}public void eat() {System.out.println(name + "吃飯");}public void sleep() {System.out.println(name + "睡覺");}
}
class Dog extends Animal {public void wang() {System.out.println(name + "汪汪叫");}
}

我們為動物類提供帶有一個參數的構造方法,此時狗類繼承動物類時,就會報錯。這是因為:當子類繼承父類之后,需要先幫助父類進行構造,再構造子類自己。 那又如何幫助父類進行構造呢:在子類中調用父類的構造方法。

構造方法的作用就是對 對象中的成員變量進行初始化,因此需要先調用父類的構造方法,對從父類繼承下來的成員完成構造,再調用子類自己的構造方法,對子類中獨有的成員進行構造。

于是,我們對代碼進行修改:

class Animal {public String name;public int age;public String sex;public Animal(String name) {this.name = name;}public void eat() {System.out.println(name + "吃飯");}public void sleep() {System.out.println(name + "睡覺");}
}
class Dog extends Animal {public Dog(String name) {super(name);}public void wang() {System.out.println(name + "汪汪叫");}
}

在這里插入圖片描述
總結一下:

1.當父類顯式定義無參或者使用默認提供的構造方法時,子類構造方法的第一行均默認有隱藏的super()調用,即調用父類構造方法。
2.如果父類的構造方法帶有參數,則需要顯式定義子類的構造方法,并在子類構造方法中調用合適的父類構造方法。
3.在子類構造方法中,super()只能出現在子類構造方法的第一行,因此子類構造方法中只能出現一次super()。

六、super和this辨析


【相同點】
1.均為Java中的關鍵字。
2.均可以對成員進行訪問,且super()和this()都需要在構造方法的首行使用,因此不能同時存在于同一個構造方法。
3.只能在類的非靜態方法中使用,用于訪問非靜態的成員。


【不同點】
1.this代表當前對象的引用,當前對象即調用成員的對象;super代表在子類對象中 對從父類繼承下來的成員 的引用。
2.在非靜態成員方法中,this既可以訪問子類的成員,也可以訪問父類的成員;super只能訪問父類的成員。
3.在構造方法中,this()用于調用當前類中的構造方法;super()用于調用父類的構造方法。
4.當子類繼承父類后,子類的構造方法中一定會存在super()語句,哪怕沒有顯式定義,編譯器也會自動添加;this()不寫則沒有。


七、再談初始化

在上一章節中,我們已經學習了有關代碼塊的知識。在繼承關系中,各個代碼塊的執行順序又是怎樣的呢?

class Animal {public String name;public int age;public String sex;public Animal(String name) {this.name = name;System.out.println("動物構造");}static {System.out.println("動物靜態代碼塊");}{System.out.println("動物實例代碼塊");}
}
class Dog extends Animal {public Dog(String name) {super(name);System.out.println("小狗構造");}static {System.out.println("小狗靜態代碼塊");}{System.out.println("小狗實例代碼塊");}
}
public class Test {public static void main(String[] args) {Dog dog1 = new Dog("小狗1");System.out.println("======================");Dog dog2 = new Dog("小狗2");}
}

運行結果為:
在這里插入圖片描述
由運行結果我們可以得出:

1.靜態代碼塊優先執行,且父類優先于子類執行。
2.父類的實例代碼塊和構造方法其次執行。
3.子類的實例代碼塊和構造方法最后執行。
4.靜態代碼塊只執行一次,第二次實例化對象時,父類和子類的靜態代碼塊均不再執行。

八、protected關鍵字

在這里插入圖片描述
依舊是這張圖片,我們來學習一下protected關鍵字。
在這里插入圖片描述


在這里插入圖片描述


學習了繼承之后,我們對private關鍵字再補充一點:在父類中被private修飾的成員雖然在子類中不能直接訪問,但是也繼承到了子類中。

九、繼承方式

在Java中支持單繼承、多層繼承、不同類繼承同一個類,但不支持多繼承!!!
在這里插入圖片描述

十、final關鍵字

final關鍵字可以用來修飾變量、方法和類。

final修飾變量時,表示變量不能被修改,即常量:

    public static void main(String[] args) {final int a = 10;a = 20; //×}

final修飾類時,代表類不能被繼承:

final class A {
}
//錯誤×
class B extends A {
}

被final修飾的類,也叫密封類。

final還可以修飾方法,這一點我們以后再介紹。


我們來看一段代碼:

        final int[] array = {1,2,3,4,5};array = new int[10]; //1array[0] = 10; //2

這段代碼會在1處報錯:
在這里插入圖片描述

十一、繼承與組合

如果將繼承比作is-a的關系,那么組合就是has-a的關系。

組合和繼承類似,也是一種表達類和類之間關系的方式,也可以達到代碼復用的效果。組合的思想體現在代碼上 就是將一個類的實例作為另一個類的成員變量,并無特殊的語法格式:

class Old {}
class Home {public Old[] olds;public Home() {this.olds = new Old[2];}
}

Ending。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88796.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS進階-day1 作用域解構箭頭函數

作用域全局作用域——>盡量少使用,避免變量污染局部作用域——>函數作用域、塊級作用域作用域鏈——>底層變量查找機制(先在當前函數作用域查找,如果找不到,就沿著作用域鏈向上級作用域查找,直到全局作用域&a…

Arduino 無線通信實戰:使用 RadioHead實現 315MHz 433M模塊數據傳輸

本文將介紹如何使用 Arduino 和 RadioHead 庫實現 315MHz(或 433MHz)ASK 無線通信。通過兩個 Arduino 控制板,一個作為發射端,一個作為接收端,實現“按鍵控制 → 無線發送 → LED 控制”的基礎通信功能,非常…

012_PDF處理與文檔分析

PDF處理與文檔分析 目錄 PDF支持概述支持的功能文檔限制上傳方式分析能力應用場景最佳實踐 PDF支持概述 核心能力 Claude現在可以直接處理PDF文檔,提供全面的文檔分析能力。這項功能支持: 文本內容分析:提取和理解PDF中的文本圖像識別&…

系規備考論文:論IT服務知識管理

論IT服務知識管理 摘要 2022年7月,我公司中標某市化工廠網絡視頻監控管理系統綜合平臺運維服務項目,并任命我為系統規劃與管理師。該項目組織結構為項目型,合同金額為115.5萬元(含稅),工期為1年。本運維服務項目的主要工作包括系統軟件和網絡設備的日常監控與維護,定期…

2025.7.12總結

最近又兩三天沒寫總結了,如今必須要寫一稿,畢竟事關賺錢認知的一次顛覆。在我原有的認知里,賺錢,就是通過出賣自己的勞動時間,精力,給他人提供價值輸出。但是,賺錢,只能通過出賣體力…

把 DNA 當 PCIe:一條 365 nt 鏈實現 64 Gbps 片上光互連——基于鏈式 F?rster 共振的分子級波分復用鏈路

作者 | Blossom.118 2025-07-13 關鍵詞:DNA 光子學、FRET 波分復用、分子 PCIe、零能耗光鏈路、CMOS 兼容、開源版圖 ---- 1. 為什么用 DNA 做光互連? ? 帶寬密度:硅光 1 m 波導最高 0.4 Tbps/mm;一條 2 nm 直徑的 DNA 雙鏈&am…

[論文閱讀]Text Compression for Efficient Language Generation

Text Compression for Efficient Language Generation [2503.11426] Text Compression for Efficient Language Generation NAACL 2025 提出了“Generative Pretrained Thoughtformer”(GPTHF),這是一個分層 transformer 語言模型&#xf…

SwiftUI 7 新 WebView:金蛇出洞,網頁江湖換新天

概述 崇禎年間,華山派武學雖盛,卻在應對江湖新局時漸顯頹勢;如今 SwiftUI 江湖亦是如此 ——WWDC 25 之前,若要在 SwiftUI 中顯示網頁,開發者恰似袁承志初闖江湖,縱有一身本領,卻苦無稱手兵刃。…

LeetCode|Day9|976. 三角形的最大周長|Python刷題筆記

LeetCode|Day9|976. 三角形的最大周長|Python刷題筆記 🗓? 本文屬于【LeetCode 簡單題百日計劃】系列 👉 點擊查看系列總目錄 >> 📌 題目簡介 題號:976. 三角形的最大周長 難度&#x…

華擎B150M Pro4S魔改bios上8代U

100、200系主板魔改bios在DIY領域當屬于歷史性事件,2018年左右興起。雖然現在已經是2025年,魔改bios已經沒有多大意義,但是跟著前輩的教程魔改一次,可以重溫下當年DIY玩家的激情。 魔改教程在SMXDIY網站,寫的非常詳細&…

音視頻學習(三十七):pts和dts

概念 PTS(Presentation Time Stamp)顯示時間戳 表示:該幀應該在什么時間被顯示/播放。主要用于:同步音頻與視頻,控制播放節奏。舉例:視頻幀 A 的 PTS 是 300ms,表示應在視頻播放第 300 毫秒時顯…

關于數據庫的慢查詢

1.數據庫的慢查詢慢查詢是指執行時間超過預設閾值的數據庫查詢操作。它是數據庫性能優化的一個重要指標和切入點。慢查詢的主要特點執行時間長:超過了數據庫系統設定的慢查詢閾值(如MySQL默認是10秒)資源消耗大:可能占用大量CPU、…

【Rust日報】 Python 核心開發者對 Rust 的期望

半月刊:The Embedded Rustacean Issue #49亮點:📢 樂鑫 DevCon 2025 演講嘉賓征集🦺 CISA 和 NSA 參與內存安全對話🔐 微軟宣布 RIFT (Rust 惡意軟件分析工具)💰? Nordic 收購 Memf…

vue是什么

Vue簡介Vue(Vue.js)是一個用于構建用戶界面的漸進式JavaScript框架。它專注于視圖層,易于集成到現有項目中,也可用于開發復雜的單頁面應用(SPA)。Vue的核心特點是輕量、靈活和高效,通過數據綁定…

10分鐘掌握 Nginx 配置文件結構

在實際部署前端或后端項目時,Nginx 配置文件(nginx.conf) 是我們無法繞開的第一道門檻。 本文將帶你用10分鐘掌握 nginx.conf 的核心結構與常見配置方法,并提供一篇完整的實戰文檔鏈接,適合初學者快速掌握。 &#x1…

典型的前后端交互數據示例

提供幾種典型的前后端交互數據示例: 前端如何組織數據,以及后端如何接收數據。 文章目錄1. POST請求后端實體類接收前端js后端接收結果查看2. GET請求后端實體類接收前端js后端接收結果查看3. GET請求后端基本類型接收前端js后端接收結果查看1. POST請求…

計算機畢業設計springboot影視周邊推薦系統 基于SpringBoot的電影衍生品智能推薦平臺 JavaWeb實現的影視文化周邊個性化服務系統

計算機畢業設計springboot影視周邊推薦系統6c31q9 (配套有源碼 程序 mysql數據庫 論文) 本套源碼可以在文本聯xi,先看具體系統功能演示視頻領取,可分享源碼參考。疫情之后,線上娛樂需求激增,人們對電影及其衍生商品的關…

(4)機器學習小白入門YOLOv :圖片標注實操手冊

(1)機器學習小白入門YOLOv :從概念到實踐 (2)機器學習小白入門 YOLOv:從模塊優化到工程部署 (3)機器學習小白入門 YOLOv: 解鎖圖片分類新技能 (4)機器學習小白入門YOLOv :圖片標注實操手冊 (5)機器學習小白入門 YOLOv:…

【JMeter】調試方法

文章目錄取樣器:發送請求、接收響應>>察看結果樹斷言:驗證響應>>察看結果樹提取器:創建變量>>調試取樣器自定義斷言:代碼>>日志了解JMeter的內部細節,排查錯誤的原因。取樣器:發送…

Vue框架之鉤子函數詳解

Vue框架之生命周期主要鉤子函數詳解一、Vue生命周期的整體流程二、創建階段:初始化組件實例2.1 beforeCreate:實例創建前2.2 created:實例創建后三、掛載階段:組件與DOM結合3.1 beforeMount:掛載前3.2 mounted&#xf…