JavaSE-繼承

繼承(inheritance)

繼承的意義

我們首先來看下面兩個類:

public class Dog {public String name;public int age;public void eat(){System.out.println(this.name+"正在吃飯");}public void bark(){System.out.println(this.name+"正在汪汪叫");}
}
public class Cat {public String name;public int age;public void eat(){System.out.println(this.name+"正在吃飯");}public void miao(){System.out.println(this.name+"正在喵喵叫");}
}

這兩個名為Dog和Cat的類擁有相同的成員變量name、age以及相同的成員方法eat

在主方法中可以正常調用他們的變量和方法。

public class test {public static void main(String[] args) {Dog dog = new Dog();dog.name="大黃";dog.eat();dog.bark();System.out.println("============");Cat cat = new Cat();cat.name="大橘";cat.eat();cat.miao();}
}

?我們可以發現在Dog和Cat中就具有相同的成員,如果每次新建一個動物類時都要加入這些相同成員,未免有些麻煩,于是繼承出現了。

如何繼承

新建一個Animals類,將動物所具有的共同成員放入其中并刪去原來類中的共同成員。

public class Animals {public String name;public int age;public void eat(){System.out.println(this.name+"正在吃飯");}
}

在原來的類名后加上extends Animals。

格式如下:

修飾符 class 子類名 extends 父類名{
}?

public class Dog extends Animals{public void bark(){System.out.println(this.name+"正在汪汪叫");}
}
public class Cat extends Animals{public void miao(){System.out.println(this.name+"正在喵喵叫");}
}

這樣原來的主函數依然可以正常運行。Animals就稱為父類/基類/超類,Dog和Cat就叫做子類或者派生類。通過繼承,我們實現了代碼的復用。

繼承中的訪問與調用

子類訪問父類成員變量

下面三段代碼分別是子類,父類和主方法。

package demo2;public class Derived extends Base{public int c=3;public void func(){System.out.println(this.a);System.out.println(this.b);System.out.println(this.c);}
}
package demo2;public class Base {public int a=1;public int b=2;
}
package demo2;public class test {public static void main(String[] args) {Derived derived =new Derived();derived.func();}
}

運行結果:

?子類訪問了繼承自父類的a和b,并訪問了自身的成員變量c。

在子類中加入a=100:

package demo2;public class Derived extends Base{public int c=3;public int a=100;public void func(){System.out.println(this.a);System.out.println(this.b);System.out.println(this.c);}
}

運行結果:

可見當父類和子類中同時出現變量a時,this關鍵字訪問的是子類自身的a。

如何在子類中訪問父類中的同名變量a?

使用super關鍵字。

package demo2;public class Derived extends Base{public int c=3;public int a=100;public void func(){System.out.println(super.a);System.out.println(this.b);System.out.println(this.c);}
}

運行結果:

?在子類方法中或者通過子類對象訪問成員時:

1.如果訪問的成員變量子類中有,優先訪問自己的成員變量。

2.如果訪問的成員變量子類中無,則訪問父類繼承下來的,如果父類中也無,則編譯報錯。

3.如果訪問的成員變量與父類中的成員變量同名,則優先訪問自己的。

子類訪問父類成員方法

當子類中成員方法與父類中成員方法不同名時,可以直接在子類中調用父類成員方法:

public class Base {public int a=1;public int b=2;public void testBase(){System.out.println("testBase---");}
}
public class Derived extends Base{public int c=3;public int a=100;public void testDerived(){System.out.println("testDerived---");}public void test(){testBase();testDerived();}
}

public class test {public static void main(String[] args) {Derived derived =new Derived();derived.test();}
}

運行結果:

?當子類中方法與父類中方法重名時,優先就近原則調用子類自己的方法,同時可以構成方法的重載和方法的重寫:

方法的重載:

public class Base {public int a=1;public int b=2;public void testA(){System.out.println("testA()---");}
}public class Derived extends Base{public int c=3;public int a=100;public void testA(char a){System.out.println("testA(char a)---");}public void test(){testA();testA('a');}
}public class test {public static void main(String[] args) {Derived derived =new Derived();derived.test();}
}

?并且可以使用super關鍵字調用父類方法:

public class Base {public int a=1;public int b=2;public void testA(){System.out.println("testA(Base)---");}
}public class Derived extends Base{public int c=3;public int a=100;public void testA(){System.out.println("testA(Derived)---");}public void test(){testA();super.testA();}
}public class test {public static void main(String[] args) {Derived derived =new Derived();derived.test();}
}

運行結果:

但是super只能指代父類,不能指代父類的父類玩套娃。

當子類繼承父類之后,在不使用構造方法的情況下,java會自動為子類和父類提供構造方法,但當我們為類添加構造方法時,子類需要顯式的調用父類的構造方法,幫助父類完成初始化。

public class Animals {public String name;public int age;public void eat(){System.out.println(this.name+"正在吃飯");}public Animals(String name,int age){this.name=name;this.age=age;}
}public class Dog extends Animals {public void bark(){System.out.println(this.name+"正在汪汪叫");}public Dog(String name,int age){super(name,age);}
}public class test {public static void main(String[] args) {Dog dog = new Dog("大黃",3);System.out.println("name:"+dog.name+" age:"+dog.age);}
}

簡而言之,當為父類添加構造方法時,需要同時在子類中添加構造方法并在第一行使用super關鍵字幫助父類初始化。

super和this關鍵字

1.super()和this()構造方法只能在第一行使用,并且不能同時出現。?

2.在非靜態成員方法中,this用來訪問本類中的方法和屬性,super用來訪問繼承父類中的方法和屬性。

3.在構造方法中,this()用于調用本類構造方法,super()用于調用繼承父類的構造方法,兩種調用不能同時在構造方法中出現。

4.構造方法中一定會有super()的調用,即使用戶沒有寫編譯器也會添加,但this()用戶不寫則沒有。

繼承中的代碼塊運行順序

猜測下列標號代碼塊的運行順序:

public class Animals {public String name;public int age;static{System.out.println("static::Animal{}");}//1{System.out.println("實例化代碼塊 Animal");}//2public Animals(String name,int age){this.name=name;this.age=age;System.out.println("Animal()");}//3
}public class Cat extends Animals {static{System.out.println("static::Cat{}");}//4{System.out.println("實例化代碼塊 Cat{}");}//5public void miao(){System.out.println(this.name+"正在喵喵叫");}public Cat(String name,int age){super(name,age);System.out.println("Cat()");}//6
}public class test {public static void main(String[] args) {Cat cat=new Cat("大橘",4);}
}

運行結果:

運行順序是:142356

從中可以得出代碼塊的運行邏輯:先執行父類,子類的靜態代碼塊,再執行父類的實例化和初始化,再執行子類的實例化和初始化。

?繼承的權限

private:僅允許本類中調用

default:允許同包中的不同類使用

protected:允許不同包中的子類使用

public:允許不同包的非子類中使用

在繼承的權限使用中,我們要盡可能的做到封裝:即最大的私密性,隱藏內部細節,只顯露出必要的內容給使用者,能夠使用private,就盡量不要使用public。有一個暴力的方法,就是將所有的變量設置為private權限,將所有的方法設置為public權限。

final關鍵字

繼承關系不宜有太多層,一般三層為上限。final在java中對變量修飾可以將其變為不可改變的常量,對子類修飾則可以防止這個類被繼承,當它被繼承時編譯器會報錯,這個類就被稱為密封類。

繼承與組合

繼承中子類與父類的關系可以表示為子類 is a 父類,而組合可以表示為前者 has a后者,或者后者 is a part of 前者,如汽車和輪胎的關系。

class Student{}class Teacher{}public class school {public Student[] student=new Student[10];public Teacher[] teacher=new Teacher[10];
}

學生和老師是學校的一部分,這就是組合關系。

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

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

相關文章

第二屆虛擬現實、圖像和信號處理國際學術會議(VRISP 2025)

重要信息 官網:www.icvisp.net 時間:2025年8月1-3日 地點:中國-長沙 簡介 近年來,虛擬現實技術取得了顯著進步,與5G、云計算和物聯網等新一代信息技術的融合加速,推動了其在硬件、軟件和內容應用等方面…

SpringBoot+Mybatis+MySQL+Vue+ElementUI前后端分離版:整體布局、架構調整(二)

目錄 一、前言 二、后端調整 1.實體類調整 2.菜單相關接口 3.用戶相關接口 4.新增工具類 5.新增菜單樹返回類 6.配置類、攔截器 三、前端調整 1.請求調整 2.頁面布局、樣式調整 1.user.vue 2.index.vue 3.請求攔截 四、開發過程中的問題 五、附&#xff1a…

vue3官方文檔學習心得

這幾天抽空把vue3的文檔整個看了一遍。簡介 | Vue.js 23年寫過一個vue2的項目,24年寫了一個vue3的項目,頁面功能比較簡單,用幾個簡單的API,watch、watchEffect、ref、reactive就能實現的業務功能。 寫了幾年的react的&#xff0…

Pycharm恢復默認設置,配置導致復制粘貼等不能使用

在file 種找到manage IDE settings在manage IDE settings中找到restore default settings

【王樹森推薦系統】召回12:曝光過濾 Bloom Filter

概述 曝光過濾通常是在召回階段做,具體的方法就是用 Bloom Filter 曝光過濾問題 如果用戶看過某個物品,則不再把該物品曝光給用戶。原因是同一個物品重復曝光給用戶會損害用戶體驗,但也不是所有推薦系統都有曝光過濾,像 youtube 這…

基于STM32單片機的心率血氧監測系統設計(STM32代碼編寫+手機APP設計+PCB設計+Proteus仿真)

系列文章目錄 文章目錄 系列文章目錄前言1 資料獲取與演示視頻1.1 資料介紹1.2 資料獲取1.3 演示視頻 2 系統框架3 硬件3.1 主控制器3.2 顯示屏3.3 WIFI模塊3.4心率血氧傳感器 4 設計PCB4.1 安裝下載立創EDA專業版4.2 畫原理圖4.4 使用嘉立創下單助手進行下單,打板。…

main(int argc,char **agrv)的含義

今天和大家討論一個常見的但是不容易深入了解的知識點。那就是 main 函數聲明中使用到的 argc 和 argv 的含義。通常我們寫主函數的時候一般都是直接使用int main() 或者 void main() 來聲明 main 函數。但是你知道嗎?在c89/c99的語言標準中,main函數的聲…

如何簡單實現發版不影響客戶使用?nginx負載

nginx負載發版不影響客戶使用 1.需要二臺服務器 2.二臺服務器均是正式環境配置 3.服務器Nginx配置修改 發版順序:先在服務器2發版,發布成功后,再改服務器Nginx配置,重新加載nginx;然后在服務器再發版,發布成…

qt筆記(1)——Qtablewidget使用

1.基礎使用方法 (略) 2.坑和注意點 2.1 設置一個單元格的編輯屬性 在代碼中,想要修改一個單元格的編輯屬性,需要對這個item的flags進行設置;注意對一個tablewidget的一個item成員進行設置后,進行一次編…

字符串的模糊匹配方法介紹

字符串的模糊匹配方法介紹 目錄字符串的模糊匹配方法介紹一、編輯距離(Levenshtein Distance)復雜度分析二、Jaro-Winkler 距離復雜度分析三、最長公共子序列(LCS)復雜度分析四、模糊搜索(Fuzzy Search)復雜…

ActiveMQ在Spring Boot中的詳細使用指南

?? 目錄 ?? ActiveMQ簡介 什么是ActiveMQ? 核心概念 ??? 基礎架構組件 ?? 重要概念解釋 ActiveMQ vs 其他消息中間件 ?? 環境搭建 1. ActiveMQ服務端安裝 Docker方式(推薦初學者) 手動安裝方式 2. 驗證安裝 訪問Web管理界面 連接參數 測試連接 ?…

二元一次方程

前言 最近剛學二元一次方程,想寫一篇專欄熟悉一下本文寫給初一的同學看,學過的就劃了吧二元一次方程 兩個未知數最高項次數為 111 次為整式方程二元一次方程的解不唯一,但是二元一次方程可以用一個未知數來表達另一個未知數eg:eg:eg: xy1x y…

AI編程的未來是智能體原生開發?

目錄 前言 一、從“串行”到“并行”:什么是智能體原生開發? 1.1 傳統模式(串行思維) 1.2 智能體原生模式(并行思維) 二、程序員的新角色:從代碼手藝人到系統思想家 三、軟件開發的終局&a…

【牛客刷題】小紅的與運算

文章目錄 一、題目介紹1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 示例二、 解題思路2.1 核心算法設計2.2 性能優化關鍵2.3 算法流程圖三、解法實現3.1 解法一:基礎實現3.1.1 初級版本分析3.2 解法二:優化版本(推薦)3.2.1 優化版本分析四、總結與拓展4.1 關鍵優化技術4.2 算…

spring中 方法上@Transation實現原理

Spring中Transactional注解方法實現原理Spring的Transactional注解在方法級別實現事務管理的原理主要基于動態代理和攔截器機制,以下是其核心實現流程:1. 代理創建階段當Spring容器啟動時,會為帶有Transactional注解的類創建代理對象&#xf…

qt-C++語法筆記之Stretch與Spacer的關系分析

qt-C語法筆記之Stretch與Spacer的關系分析 code review! 文章目錄qt-C語法筆記之Stretch與Spacer的關系分析1. Stretch(拉伸因子)2. Horizontal Spacer 和 Vertical Spacer3. Stretch 和 Spacer 的關系4. 實際應用中的選擇5. 注意事項6. 代碼與 Qt Desig…

Qwen3技術綜述

1. 引入 2025年5月,qwen推出了旗艦模型(flagship model)Qwen3-235B-A22B。并以Apache 2.0版權發布(可自由商業使用,修改代碼和商用要包含原始版權)。本文對其技術報告中提到的數據處理技術與模型結構進行綜…

[特殊字符] Excel 讀取收件人 + Outlook 批量發送帶附件郵件 —— Python 自動化實戰

許多公司定期需要將不同部門或客戶的報告發送給指定人員。手動操作容易出錯、耗時且繁瑣。今天這篇文章教你如何利用 Python 實現: 🧩 從 Excel 中讀取“收件人 抄送人 附件文件路徑”; 📤 使用 win32com.client 調用 Outlook …

多模態大語言模型arxiv論文略讀(152)

VidComposition: Can MLLMs Analyze Compositions in Compiled Videos? ?? 論文標題:VidComposition: Can MLLMs Analyze Compositions in Compiled Videos? ?? 論文作者:Yunlong Tang, Junjia Guo, Hang Hua, Susan Liang, Mingqian Feng, Xinya…

基于AR和SLAM技術的商場智能導視系統技術原理詳解

本文面對室內定位算法工程師、智慧商場系統開發者、對VR/AR應用開發感興趣的技術人員,解決如何通過SLAMAR技術破解大型商場室內導航的空間認知壁壘,實現沉浸式導覽,本文提供完整技術方案與代碼實現。 如需獲取商場智能導視系統解決方案請前往…