【JAVA】面向對象三大特性之繼承

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 前言
  • 一、繼承的概念和使用細則
    • 1.1 繼承的基本使用和含義
    • 1.2 關于子類訪問父類成員的問題
    • 1.3 super關鍵的引出
    • 1.4 super調用父類當中指定的構造方法
    • 1.5 關于super和this
    • 1.6 繼承關系上的代碼塊執行順序
    • 1.7 訪問修飾限定符-protected關鍵字
    • 1.8 java中的繼承方式
    • 1.9 final關鍵字
  • 二、繼承和組合
  • 總結


前言

提示:這里可以添加本文要記錄的大概內容:

繼承作為面向對象編程的核心支柱,通過對類之間共性的高效抽取實現代碼復用,為構建層次化、可擴展的軟件系統奠定堅實基礎。


提示:以下是本篇文章正文內容,下面案例可供參考

一、繼承的概念和使用細則

1.1 繼承的基本使用和含義

繼承(inheritance)機制:是?向對象程序設計使代碼可以復?的最重要的?段,它允許程序員在保持原有類特性的基礎上進?擴展,增加新功能,這樣產?新的類,稱派?類。

繼承的目的就是對不同類之間進行共性的抽取,從而來實現代碼的復用!!!!!!

在這里插入圖片描述
被繼承的類稱為父類、基類和超類,繼承別人的類稱為子類和派生類,和生活中的情形很接近所以很好理解。
在代碼中,繼承最大的特性就是子類可以繼承父類當中的成員變量和成員方法!!

接下來對上述圖示中的類之間的關系,利用繼承用代碼進行實現。

package com.dzj;public class Animal {public String name;public int age;public float weight;public void eat(){System.out.println(name+"---吃東西---");}public void sleep(){System.out.println(name+"開始睡覺~~~~~");}
}
package com.dzj;public class Cat extends Animal{public void mew(){System.out.println(name+"喵喵喵");}
}
package com.dzj;public class Dog extends Animal{public void bark(){System.out.println(this.name+"狗叫");}
}
package com.dzj;public class TestExtend {public static void main(String[] args) {Cat cat=new Cat();cat.name="hzp";cat.eat();cat.sleep();cat.mew();Dog dog=new Dog();dog.name="xxx";dog.eat();dog.sleep();dog.bark();}
}

在這里插入圖片描述

1.2 關于子類訪問父類成員的問題

關于這個問題,只要遵循一個就近原則即可:如果子類有優先訪問子類的,子類沒有的再去父類找!!!!

子類和父類不存在同名成員變量

package com.demo1;public class Base {int a=10;int b=20;
}
package com.demo1;public class Derived extends Base{int c=30;public void method(){System.out.println(a);System.out.println(b);System.out.println(c);}
}
package com.demo1;public class Test {public static void main(String[] args) {Derived derived=new Derived();derived.method();}
}

在這里插入圖片描述
結果表明,如果子類和父類不存在同名的成員變量,子類可以直接訪問父類的成員變量。

如果子類和父類存在同名成員變量:

package com.demo1;public class Base {int a=10;int b=20;
}
package com.demo1;public class Derived extends Base{int a=100;int b=200;int c=30;public void method(){System.out.println(a);System.out.println(b);System.out.println(c);}
}
package com.demo1;public class Test {public static void main(String[] args) {Derived derived=new Derived();derived.method();}
}

在這里插入圖片描述
結果表明,如果父子類出現同名的成員變量,優先使用子類的成員變量,即遵循就近原則。

對于子類訪問父類的成員方法其實原理比較類似,接下來直接上代碼解釋:

package com.demo1;public class Base {int a=10;int b=20;public void methodA(){System.out.println("Base的methodA--------");}public void methodB(int x){System.out.println("Base的methodA--------");System.out.println(x);}
}
package com.demo1;public class Derived extends Base{int a = 100;int b = 200;int c = 30;public void method(){System.out.println(a);System.out.println(b);System.out.println(c);}public void methodA(){System.out.println("Derived的methodA--------");}public void methodB(){System.out.println("Derived的mmethodB--------");}public void methodC(){System.out.println("Derived的methodC--------");}
}
package com.demo1;public class Test {public static void main(String[] args) {Derived derived=new Derived();derived.methodA();derived.methodB();derived.methodB(100);derived.methodC();}
}

在這里插入圖片描述
從結果可以看出整個調用過程還是遵循就近原則的,唯一需要注意的是成員方法本身是支持重載的,如果存在方法的重載根據所給參數的不同來確定最后調用的是哪一個成員方法。

1.3 super關鍵的引出

問題:如果?類中存在與?類中相同的成員時,那如何在?類中訪問?類相同名稱的成員呢?,也就是說如果存在同名的情況,我一定要訪問父類的成員變量和成員方法怎么做???

答案就是利用super關鍵字,接下來將用代碼進行演示super關鍵的作用,最后在做一個小的總結。

package com.demo1;public class Base {int a=10;int b=20;public void methodA(){System.out.println("Base的methodA--------");}public void methodB(int x){System.out.println("Base的methodA--------");System.out.println(x);}
}
package com.demo1;public class Derived extends Base{int a = 100;int b = 200;int c = 30;public void method(){System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(super.a);System.out.println(super.b);super.methodA();}public void methodA(){System.out.println("Derived的methodA--------");}public void methodB(){System.out.println("Derived的mmethodB--------");}public void methodC(){System.out.println("Derived的methodC--------");}
}
package com.demo1;public class Test {public static void main(String[] args) {Derived derived=new Derived();/*derived.methodA();derived.methodB();derived.methodB(100);derived.methodC();*/derived.method();}
}

在這里插入圖片描述
從結果可以看出,在子類成員方法中可以使用super關鍵字訪問父類的成員變量和成員方法

注意事項
**1. 只能在非靜態?法中使用(和this關鍵字一樣)

  1. 在?類?法中,訪問?類的成員變量和?法。**

1.4 super調用父類當中指定的構造方法

package com.demo2;public class Base {public Base(int x){System.out.println("Base構造方法");System.out.println(x+"----"+x);}
}
package com.demo2;public class Derived extends Base{public Derived() {System.out.println("Derived構造方法");}
}
package com.demo2;import com.demo1.Derived;public class Test {public static void main(String[] args) {Derived derived=new Derived();}}

在這里插入圖片描述
上述結果表明Base構造方法缺少參數,出現錯誤的原因就是,在構建子類對象的同時,要先完成父類的構造函數初始化在完成子類構造函數的初始化!

public class Derived extends Base{public Derived() {super(100);System.out.println("Derived構造方法");}
}

稍作修改就可以編譯成功!
在這里插入圖片描述
【注意事項】
? 通過super(參數)的形式可以調??類指定的構造?法
? super()的形式只能出現在?類的構造?法當中且必須在第??

再思考一個問題:先看如下代碼

package com.demo2;public class Base {public Base(){System.out.println("Base構造方法");/*System.out.println(x+"----"+x);*/}
}
package com.demo2;public class Derived extends Base{public Derived() {/*super(100);*/System.out.println("Derived構造方法");}
}
package com.demo2;import com.demo2.Derived;public class Test {public static void main(String[] args) {Derived derived=new Derived();}
}

在這里插入圖片描述
代碼可以正常運行!!!為什么這里沒用super也能跑,因為再子類構造方法的第一行系統默認會加上一個super()調用父類無參構造方法。僅限?類的構造?法是不帶參數的構造?法且只有這?個的情況下。
另外補充一點,super()和this()是不能一起使用的!!!,因為他們都要求放在構造函數第一行上

1.5 關于super和this

【相同點】
1. 都是Java中的關鍵字
2. 只能在類的?靜態?法中使?,?來訪問?靜態成員?法和字段
3. 在構造?法中調?時,必須是構造?法中的第?條語句,并且不能同時存在

【不同點】
1. this是當前對象的引?,當前對象即調?實例?法的對象,super相當于是?類對象中從?類繼承下
來部分成員的引?

在這里插入圖片描述
從圖中可以看出,super和this指向的是不同的空間。
2. 在?靜態成員?法中,this?來訪問本類的?法和屬性,super?來訪問?類繼承下來的?法和屬性
4. 在構造?法中:this(…)?于調?本類構造?法,super(…)?于調??類構造?法,兩種調?不能同時在構造?法中出現
5. 構造?法中?定會存在super(…)的調?,??沒有寫編譯器也會增加,但是this(…)??不寫則沒有

1.6 繼承關系上的代碼塊執行順序

package com.demo3;
public class Person {String name;int age;public Person(String name,int age){this.name=name;this.age=age;System.out.println("Person:構造方法執行");}{System.out.println("Person:實例代碼塊執行");}static{System.out.println("Person:靜態代碼塊執行");}
}
package com.demo3;public class Student extends Person{
public Student(String name,int age){super(name,age);System.out.println("Student:構造方法執行");
}{System.out.println("Student:實例代碼塊執行");}static{System.out.println("Student:靜態代碼塊執行");}
}
package com.demo3;public class Test {public static void main(String[] args) {Student student1=new Student("dzj",18);System.out.println("--------------------");Student student2=new Student("dzj",18);}
}

在這里插入圖片描述

通過分析執?結果,得出以下結論:
1. ?類靜態代碼塊優先于?類靜態代碼塊執?,且是最早執?。
2. ?類實例代碼塊和?類構造?法緊接著執?。
3. ?類的實例代碼塊和?類構造?法緊接著再執?。

4. 第?次實例化?類對象時,?類和?類的靜態代碼塊都將不會再執?

1.7 訪問修飾限定符-protected關鍵字

在這里插入圖片描述
如果被protected 關鍵字修飾該類當中成員變量,成員?法等表?要么只能在同?個包中的類中進?訪問,要么在不同包中只能通過在繼承關系上的?類對象來訪問

package com.demo2;public class Base {/*  public Base(){System.out.println("Base構造方法");*//*System.out.println(x+"----"+x);*//*}*/protected int x=100;
}
package com.demo3;import com.demo2.Base;public class Derived extends Base {public static void main(String[] args) {Derived derived=new Derived();System.out.println(derived.x);}
}

在這里插入圖片描述
打印結果表明:不同包下的子類可以訪問父類中被protected修飾的成員變量.

特殊情況:

package com.demo3;import com.demo2.Base;
class C extends Base{public static void main(String[] args) {C c=new C();System.out.println(c.x);}
}public class Derived extends Base {public static void main(String[] args) {Derived derived=new Derived();System.out.println(derived.x);C c=new C();System.out.println(c.x);}
}

在這里插入圖片描述
雖然Derived 類繼承?Base 類,但它不能訪問其他 Base 類?類(這?是C類)實例的protected 成員。可能感覺比較抽象,一個簡單的理解就是要訪問protected修飾的變量,那么只能在本類中用自己的對象去訪問,不能用別人的,所以個人認為這個protected的訪問有比較大的局限性。
總結:
如果在情況允許下,能用private就用private,這樣能最大程度的保持封裝性,因此我們在使?的時候應該盡可能的使??較嚴格的訪問權限。

1.8 java中的繼承方式

在這里插入圖片描述
java中不允許多繼承的存在,?般我們不希望出現超過三層的繼承關系

1.9 final關鍵字

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

final修飾變量即為常量,不可以發生改變

public final class Animal {
}
public class Bird extends Animal{}

final修飾類即為不可繼承
final修飾方法即為該方法不可以被重寫,這一點再后續的博客中再講解。

二、繼承和組合

繼承表?對象之間是is-a的關系,?如:狗是動物,貓是動物
組合表?對象之間是has-a的關系,?如:汽?

用代碼來解釋更清楚:

package com.demo4;public class Car {private Tire tire;private Engine engine;public Tire getTire() {return tire;}public void setTire(Tire tire) {this.tire = tire;}public Engine getEngine() {return engine;}public void setEngine(Engine engine) {this.engine = engine;}
}
package com.demo4;public class Engine {int size;
}
package com.demo4;public class Tire {String color;
}
package com.demo4;public class Benz extends Car{public static void main(String[] args) {Benz benz =new Benz();Tire tire=new Tire();Engine engine=new Engine();engine.size=100;tire.color="黑色";benz.setTire(tire);benz.setEngine(engine);System.out.println(benz.getEngine().size);System.out.println(benz.getTire().color);}}

在這里插入圖片描述
組合和繼承都可以實現代碼復?,應該使?繼承還是組合,需要根據應?場景來選擇,?般建議:能?組合盡量?組合,繼承層次太深的代碼不利于維護。

總結

從基礎使用到訪問控制,從super關鍵字到代碼塊執行順序,深入理解繼承機制能顯著提升代碼復用性和可維護性,但需警惕過度繼承帶來的設計復雜性,合理運用final和組合優化架構。

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

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

相關文章

基于深度學習的自動調制識別網絡(持續更新)

基于卷積神經網絡架構 CNN 參考文獻 T.J. O’Shea, J. Corgan, T.C. Clancy, Convolutional radio modulation recognition networks, in: Proc. Int. Conf. Eng. Appl. Neural Netw., Springer, 2016, pp. 213–226. MCNet 參考文獻 T. Huynh-The, C.-H. Hua, Q.-V. Pha…

Java進階---并發編程

一.線程復習1.什么是線程,進程進程是操作系統分配資源的基本單位線程是進程中的一個執行單元(一個獨立執行的任務),是cpu執行的最小單元2.Java中如何創建線程1.繼承Thread類,重寫run(),直接創建子類的對象2.類實現Runnable接口&am…

小車循跡功能的實現(第六天)

👨?💻個人主頁:開發者-削好皮的Pineapple! 👨?💻 hello 歡迎 點贊👍 收藏? 留言📝 加關注?! 👨?💻 本文由 削好皮的Pineapple! 原創 👨?&#x1f4…

C++ auto與 for循環

一、數組 #include <iostream> #include <vector> using namespace std; int main() {int vec[6] {1,2,3};for (auto num : vec) { /* num 是 int */ cout << "Hello, world!" << num <<endl;}return 0; }二、STL容器與迭代器 for 循…

【RK3568+PG2L50H開發板實驗例程】FPGA部分 | ROM、RAM、FIFO 的使用

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com) 1.實驗簡介 實驗目的&#xff1a; 掌握紫光平臺的 RAM、ROM、FIFO IP 的使用 實驗環境&#xff1a; Window11 PDS2022…

力扣-21.合并兩個有序鏈表

題目鏈接 21.合并兩個有序鏈表 class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode p1 list1;ListNode p2 list2;ListNode p new ListNode(0);ListNode cur p;while (p1 ! null && p2 ! null) {if (p1.val > p2.val) …

MoE混合專家模型:千億參數的高效推理引擎與架構革命

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; 從稀疏激活到多模態協同的智能計算范式 &#x1f9e9; 一、核心思想與…

【論文筆記】BlockGaussian:巧妙解決大規模場景重建中的偽影問題

論文地址&#xff1a;https://arxiv.org/pdf/2504.09048 大規模場景的重建方法不僅僅對于高空航拍數據有效&#xff0c;而且對于地面大中場景也有增強效果&#xff0c;故專門來學習一下這一方向的知識。感謝作者大佬們的great work。 Abstract 三維高斯潑濺&#xff08;3DGS…

網絡眾籌項目數據庫(2014-2024.11)

1727網絡眾籌項目數據庫&#xff08;2014-2024.11&#xff09;數據簡介作為新興互聯網融資模式&#xff0c;眾籌已成為越來越多創業者和中小企業獲取資金的渠道&#xff0c;但眾籌項目一直面臨融資成功率低的困難&#xff0c;成功融資的項目在許多平臺上占比不足五成。而目前對…

k8s新增jupyter服務

k8s新增服務 常用命令 kubectl apply -f xxxxxx.yaml # 部署資源&#xff0c;順序&#xff1a;namespace -> pvc -> deployment -> servicekubectl create namespace jupyter # 創建namespacekubectl get namespaces # 查看nskubectl get pods -n jupyter # 查看p…

結構化數據、非結構化數據區別

一、核心定義結構化數據&#xff1a;指具有固定格式、可直接用二維表&#xff08;如數據庫表&#xff09;表示的數據&#xff0c;其字段&#xff08;列&#xff09;定義明確&#xff0c;數據之間的關系清晰。例如&#xff1a;Excel 表格中的數據、關系型數據庫&#xff08;MySQ…

Linux修煉:基礎指令

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》、《Linux修煉&#xff1a;終端…

【Linux網絡】深入理解HTTP/HTTPS協議:原理、實現與加密機制全面解析

協議是通信雙方必須遵守的規則&#xff0c;確保數據能夠正確傳輸和解析&#xff0c;它規定了數據格式、傳輸順序、錯誤處理等細節。應用層的協議一般都是我們自己進行定義的&#xff0c;但是有很多程序員前輩已經寫出來了很哇塞的協議&#xff0c;我們直接進行學習和使用即可HT…

淺嘗 Spring AI【使用超級簡單~】

一直想要體驗下 Spring AI&#xff0c;最近自己的一個工具有這個需求&#xff0c;所以這里準備使用下。其實使用起來超級簡單。 1.IDEA 新建 Spring項目 1&#xff09;這里可以根據自己的喜好選擇 項目名、jdk版本等 2&#xff09;這里選擇 在ai中選擇 openAI 即可。然后我另…

DDL期間TDSQL異常會話查詢造成數據庫主備切換

問題描述&#xff1a;7*24聯機交易系統&#xff0c;傍晚時分&#xff0c;從客戶端后臺對3千萬行的大表執行縮短varchar類型字段長度的ddl語句&#xff0c;執行期間&#xff0c;為了查看ddl進度&#xff0c;從TDSQL-MySQL赤兔前端頁面點擊異常會話查詢&#xff0c;之后數據庫卡住…

弧焊機器人氣體全方位節能指南

氬弧焊&#xff08;TIG焊接&#xff09;作為其中一種高效且精密的技術&#xff0c;憑借其穩定性和高質量的焊接效果&#xff0c;在航空航天、汽車制造、船舶建造以及石油化工等領域占據了不可或缺的地位。氬弧焊通過使用惰性氣體&#xff08;如氬氣&#xff09;保護電弧和熔池&…

數據清洗(ETL/ELT)原理與工具選擇指南:企業數字化轉型的核心引擎?

目錄 一、數據清洗&#xff08;ETL/ELT&#xff09;到底在干啥&#xff1f; 1.揪出并處理異常值 2.把缺失的數據補上&#xff08;或處理好&#xff09; 3.數據轉換與標準化 4.一致性校驗 二、工具怎么選&#xff1f;看菜吃飯&#xff0c;量體裁衣 1.數據量不大、要求不高…

阿里云服務器,CentOS7.9上安裝YApi 接口管理平臺

目錄 1.node安裝 1.1下載node,解壓 1.2 部署bin文件 1.3 安裝mongodb 2.啟動yapi 2.1 前置命令 2.2 啟動服務 3.利用pm2方便服務管理維護 3.1.安裝pm2 3.2 常用 PM2 命令 4.常見問題 4.1. 確認 MongoDB 是否安裝 4.2. 安裝 MongoDB&#xff08;若未安裝&#xff…

阿里云錯題集分享

有最近想要考試阿里云的可以私信我 &#xff0c;一起加油錯題集1.在使用阿里云的負載均衡SLB實例時&#xff0c;做了如下健康檢查的配置:成功響應和超時響應時間均為1秒&#xff0c;健康檢查間隔為2秒&#xff0c;不健康閾值為3&#xff0c;健康閾值為3。即對于確認一個云服務器…

Android 12 - 部分相機橫屏顯示方案

1.相機過渡界面方向旋轉 Android 10 - 相機過渡界面默認角度 同A10 有些區別&#xff0c;再次增加記錄修改。 這個文件沒有修改&#xff0c;只是說明 src/com/android/camera/CameraActivity.javaprivate void freezeScreenCommon(boolean async) {long startTime System.…