Java繼承機制詳解:從原理到實戰應用

一、繼承的本質:消除冗余,構建邏輯關系

想象一個公司管理系統:普通銷售員工(CommissionEmployee)和帶底薪銷售員工(BasePlusCommissionEmployee)共享大部分屬性(姓名、工號、銷售額、傭金率)。沒有繼承時,代碼會變成這樣:

// 普通銷售員工類
class CommissionEmployee {private String name;private String identityNumber;private double grossSales;private double commissionRate;// 構造器和方法...
}// 帶底薪銷售員工類
class BasePlusCommissionEmployee {private String name;          // 重復private String identityNumber; // 重復private double grossSales;     // 重復private double commissionRate; // 重復private double baseSalary;     // 特有屬性// 構造器和方法...
}

這種設計存在三大問題:

  1. 代碼冗余:相同屬性在多處重復
  2. 維護成本高:修改公共屬性需同步所有類
  3. 關系缺失:未體現"帶底薪員工也是銷售員工"的邏輯

繼承解決方案:

class CommissionEmployee { /* 公共屬性 */ }
class BasePlusCommissionEmployee extends CommissionEmployee { private double baseSalary; // 僅定義特有屬性
}

img


二、訪問控制:protected與封裝的藝術

繼承中,子類如何訪問父類屬性?核心在于訪問修飾符:

class Parent {private int x;    // 僅本類可訪問protected int y;  // 子類可訪問
}class Child extends Parent {void demo() {// System.out.println(x); // 錯誤!private不可訪問System.out.println(y);   // 正確,protected允許訪問}
}

最佳實踐

class CommissionEmployee {private double grossSales; // 保持封裝// 通過protected方法暴露訪問protected double getGrossSales() { return grossSales; }
}class BasePlusCommissionEmployee extends CommissionEmployee {@Overridepublic double earnings() {// 通過getter安全訪問父類屬性return baseSalary + getGrossSales() * getCommissionRate();}
}

三、構造器:super()的初始化魔法

子類必須通過super()調用父類構造器,確保繼承鏈完整:

class Employee {public Employee(String name, String id) {System.out.println("初始化員工基礎信息");}
}class Manager extends Employee {private String department;public Manager(String name, String id, String dept) {super(name, id); // 必須第一行this.department = dept;System.out.println("添加經理專屬屬性");}
}

多級繼承初始化順序

class Person {public Person() { System.out.println("Person初始化"); }
}
class Employee extends Person {public Employee() { System.out.println("Employee初始化"); }
}
class Manager extends Employee {public Manager() { System.out.println("Manager初始化"); }
}
// 創建Manager時輸出:
// Person初始化 → Employee初始化 → Manager初始化

四、方法重寫:@Override的力量

當子類需要改變父類行為時,使用方法重寫:

class Vehicle {public void startEngine() {System.out.println("啟動普通引擎");}
}class ElectricCar extends Vehicle {@Overridepublic void startEngine() {System.out.println("靜默啟動電機"); // 完全重寫}
}class HybridCar extends Vehicle {@Overridepublic void startEngine() {super.startEngine();       // 復用父類邏輯System.out.println("同時啟動電機"); // 擴展新功能}
}

img

重寫 vs 重載

// 重寫(父子類間)
class Parent { void demo(int a) {} }
class Child extends Parent { @Override void demo(int a) {} // 相同簽名
}// 重載(同一類內)
class Calculator {int add(int a, int b) { ... }      // 簽名1double add(double a, double b) { ... } // 簽名2
}

五、類層次設計:從Object到業務模型

所有Java類都隱式繼承Object,可重寫關鍵方法:

class Employee {private String name;@Overridepublic String toString() {return "員工: " + name; // 替換默認的類名@哈希值}
}

設計原則

  1. 單一職責:每層添加明確的新功能
  2. 層次扁平化:建議≤3層(如:Person→Employee→Manager)
  3. 組合優于繼承:當"has-a"比"is-a"更合理時

六、實戰:可運行的繼承案例

// 基類(父類)
class MyParent {protected int x, y;  // 子類可訪問的受保護屬性public MyParent(int x, int y) {this.x = x;this.y = y;}public int getX() { return x; }public int getY() { return y; }
}// 派生類(子類)
class MyChild extends MyParent {public MyChild(int x, int y) {super(x, y);  // 必須調用父類構造器}// 子類特有方法public int calculateSum() {return x + y; // 直接訪問父類protected屬性}
}// 測試類
public class Main {public static void main(String[] args) {MyChild obj = new MyChild(5, 3);System.out.println("從父類繼承的方法:");System.out.println("x = " + obj.getX()); // 輸出: 5System.out.println("y = " + obj.getY()); // 輸出: 3System.out.println("子類特有方法:");System.out.println("x+y = " + obj.calculateSum()); // 輸出: 8}
}

執行結果

從父類繼承的方法:
x = 5
y = 3
子類特有方法:
x+y = 8

七、繼承的四大核心價值

代碼復用

// 公共代碼在父類寫一次
class Animal {void breathe() { System.out.println("呼吸中..."); }
}
// 所有子類自動獲得呼吸能力
class Fish extends Animal {}
class Bird extends Animal {}

多態支持

Animal[] zoo = {new Fish(), new Bird()};
for(Animal a : zoo) {a.breathe(); // 不同子類統一調用
}

擴展靈活

class Bird extends Animal {@Overridevoid breathe() {super.breathe();System.out.println("氣囊輔助呼吸"); // 擴展功能}
}

系統可維護性

img


結語:明智使用繼承

繼承是把雙刃劍,遵循三條黃金法則:

  1. 嚴格驗證"is-a"關系(經理是員工?,員工是公司?)
  2. 優先用組合處理"has-a"關系(汽車有發動機→組合)
  3. 保持層次扁平(超過3層需重構)

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

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

相關文章

工業數采引擎-DTU

DTU配置注冊包及心跳包(對應設備配置->設備SN),模塊工作方式:TcpClient,首次連接成功后,DTU發送上來的注冊包作為鏈路SessionId1. ModbusRtu設備 -> Dtu -> Server2. DLT645設備 -> Dtu -> Server3. 自定義設備 -&…

AttributeError: ChatGLMTokenizer has no attribute vocab_size

請問運行下面語句tokenizer AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_codeTrue) 出現“AttributeError: ChatGLMTokenizer has no attribute vocab_size”是版本不一致,需要舊的版本卸載conda uninstall transformers或者pip un…

14.串口更新FLASH字庫

一、簡介 在使用STM32等單片機驅動顯示屏時,為了顯示中文字體,常用FLASH保存字庫信息。但是字庫的更新通常只能使用SD卡更新,在一些小型單片機系統(如STM32F103C8T6、STC89C52)上,沒有增加SD卡支持的必要。為解決此問題&#xff0…

Lombok常用注解及功能詳解

Lombok常用注解及功能詳解一、Lombok簡介與環境配置1.1 什么是Lombok?1.2 環境配置1.2.1 Maven項目1.2.2 Gradle項目1.2.3 IDE配置(關鍵)二、Lombok常用注解詳解2.1 Data:一站式生成核心方法2.2 Getter/Setter:單獨生成…

應用分層

應用分層是?種軟件開發設計思想,它將應用程序分成N個層次,這N個層次分別負責各自的職責, 多個層次之間協同提供完整的功能。根據項目的復雜度,把項目分成三層,四層或者更多層。常見的MVC設計模式,就是應用…

[特殊字符] 【JAVA進階】StringBuilder全方位解析:從使用到源碼,一文搞定!

🔥 掌握StringBuilder,讓你的Java字符串操作性能飆升!🧩 StringBuilder是什么? StringBuilder是Java中用于動態構建字符串的可變字符序列類,位于java.lang包中。與不可變的String類不同,StringB…

Redis 數據結構全景解析

Redis 不是簡單的 key-value 緩存,它更像一把“瑞士軍刀”。 只要掌握數據結構,就能把同一份內存用出 10 倍效率。0. 開場白:為什么聊數據結構? 面試常問“Redis 有幾種數據類型?”——很多人答 5 種(Strin…

ansible.cfg 配置文件的常見配置項及其說明

配置項說明默認值defaults默認配置部分inventory指定清單文件的位置,可以是文件路徑、目錄或動態清單腳本。/etc/ansible/hostsremote_user默認的遠程用戶roothost_key_checking是否啟用主機密鑰檢查。設置為 False 跳過 SSH 主機密鑰驗證。Trueask_pass是否在執行時…

Effective C++ 條款15:在資源管理類中提供對原始資源的訪問

Effective C 條款15:在資源管理類中提供對原始資源的訪問核心思想:RAII類需要提供訪問其封裝原始資源的顯式或隱式接口,以兼容需要直接操作資源的API,同時維持資源的安全管理。 ?? 1. 原始資源訪問的必要性 使用場景示例&#x…

Linux 進程管理與計劃任務設置

Linux 進程管理與計劃任務設置一、進程管理進程管理用于監控、控制系統中運行的程序(進程),包括查看進程狀態、調整優先級、終止異常進程等。以下是核心命令及操作說明:1. 常用進程查看命令(1)ps&#xff1…

MYSQL數據庫之索引

1、引入索引的問題在圖書館查找一本書的過程,可類比數據庫查詢場景。在一般軟件系統中,對數據庫操作以查詢為主,數據量較大時,優化查詢是關鍵,索引便是優化查詢的重要手段 。2、索引是什么索引是一種特殊文件&#xff…

ArcGIS以及ArcGIS Pro如何去除在線地圖制作者名單

問題:ArcGIS和ArcGIS Pro提供了許多在線地圖服務,但是這些地圖會自動生成制作者名單,如下圖所示: 在線地圖加載方式可參考:如何在ArcGIS和ArcGIS Pro中添加在線底圖 這在出圖時有時會造成圖的部分信息遮擋或出圖不美觀…

InfluxDB 與 Golang 框架集成:Gin 實戰指南(二)

四、實際應用案例4.1 案例背景某智能工廠部署了大量的物聯網設備,如傳感器、智能儀表等,用于實時監測生產線上設備的運行狀態、環境參數(如溫度、濕度)以及生產過程中的各項指標(如產量、次品率)。這些設備…

Linux系統磁盤未分配的空間釋放并分配給 / 根目錄的詳細操作【openEuler系統】

選擇 Fix 修正 GPT 表 輸入 Fix 并按回車,parted 會自動: 擴展 GPT 表的 結束位置 到磁盤末尾。釋放未被使用的空間(1048576000 個 512B 塊,約 500GB)。 驗證修正結果 修正后,再次運行: parted …

王道考研-數據結構-01

數據結構-01視頻鏈接:https://www.bilibili.com/video/BV1b7411N798?spm_id_from333.788.videopod.sections&vd_source940d88d085dc79e5d2d1c6c13ec7caf7&p2 數據結構到底在學什么? 數據結構這門課他要學習的就是怎么用程序代碼把現實世界的問題給信息化&…

k8s云原生rook-ceph pvc快照與恢復(上)

#作者:Unstopabler 文章目錄前言部署rook-ceph on kubernets條件Ceph快照概述什么是PVC安裝快照控制器和CRD1.安裝crds資源2.安裝控制器3.安裝快照類前言 Rook 是一個開源的云原生存儲編排器,為各種存儲解決方案提供平臺、框架和支持,以便與…

springcloud04——網關gateway、熔斷器 sentinel

目錄 注冊中心 nacos | eurekaServer |zookeeper(dubbo) 配置中心 nacos | config Server 遠程服務調用 httpClient | RestTemplate | OpenFeign 負載均衡服務 ribbon | loadbalancer 網關 zuul | gateway 熔斷器 hystrix | sentinel 網關 sentinel 流控 壓測工具 1…

XSS跨站腳本攻擊詳解

一、XSS攻擊簡介跨站腳本攻擊的英文全稱是Cross-Site Scripting,為了與CSS有所區別,因此縮寫為“XSS”由于同源策略的存在,攻擊者或者惡意網站的JavaScript代碼沒有辦法直接獲取用戶在其它網站的信息,但是如果攻擊者有辦法把惡意的…

Linux /proc/目錄詳解

文章目錄前言文件說明注意事項前言 在 Linux 系統中,/proc 目錄是一個特殊的虛擬文件系統,它提供了對系統內核和進程的訪問。/proc 目錄中的文件和目錄不是真實存在的,它們是在運行時由內核動態生成的,用于提供系統和進程的相關信…

北斗變形監測在地質災害監測中的應用

內容概要 北斗形變監測系統在地質災害監測領域發揮著核心作用,該系統基于北斗衛星導航技術,實現對地表變形的精確追蹤。通過毫米級精度定位能力,北斗形變監測技術為滑坡等災害提供關鍵數據支撐,尤其在偏遠地區應用中,單…