news 2026/7/17 4:13:23

Day15 --【Java全栈】面向对象编程[3]继承

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day15 --【Java全栈】面向对象编程[3]继承

继承(Inheritance)

全程沿用奶茶店统一类比体系,和封装、访问修饰符、this 知识点完全串联;从问题引入到语法实现、从核心特性到常见误区逐层拆解。


先思考一个问题: 如果我们要写「珍珠奶茶类」「芋泥奶茶类「鲜果茶类」三个类,它们都有饮品名称、价格、温度这些通用属性,也都有获取价格、饮用这些通用方法。如果每个类都把这些属性和方法重新写一遍,会出现什么问题?

最直接的问题就是:代码大量重复,修改通用逻辑要改好几个地方,维护成本高,还容易改漏。 面向对象里专门用来解决「代码复用、层级抽象」问题的特性,就是继承。


一、继承是什么

💡 通俗理解

奶茶店不会给每一款饮品单独从零设计配方模板,而是先做一份「通用饮品基础模板」,上面写清楚所有饮品都有的要素:名称、定价规则、基础制作步骤。 具体的珍珠奶茶、芋泥奶茶、果茶,都直接沿用这份基础模板,只需要补充自己独有的配料、调整专属的制作步骤就行,不用从零开始写。

对应到代码里:

  • 通用饮品模板 = 父类(基类 / 超类):抽取所有子类共有的属性和方法,是抽象的通用模板

  • 具体奶茶品类 = 子类(派生类):继承父类的所有通用内容,再扩展自己的特有属性和方法

一句话理解:继承就是「子类复用父类的属性和方法,不用重复写,还能按需扩展」。

🔴 记忆:正式定义

继承是面向对象三大核心特性之一,是实现代码复用的核心机制。它允许一个类(子类)通过关键字继承另一个类(父类)的非私有属性与方法,子类可以直接复用父类成员,也可以定义自己的专属成员,甚至重写父类的方法逻辑。

继承的三大核心价值

  1. 代码复用,减少冗余 通用属性和方法只在父类写一次,所有子类直接复用,不用重复编写,大幅减少重复代码。

  2. 层级清晰,便于扩展 把通用逻辑向上抽取到父类,子类只关注自己的专属逻辑,结构分层清晰,新增品类时只需要继承父类、补充独有内容即可。

  3. 为多态提供基础 继承是多态的前提,没有父子类的继承关系,多态就无法实现(多态后续会详细讲)。


二、继承的基础语法

1. 核心关键字:extends

Java 中通过extends关键字实现继承,语法格式:

// 子类 extends 父类 public class 子类类名 extends 父类类名 { // 子类自己的属性和方法 }

2. 基础代码示例(奶茶店场景)

先定义父类:所有饮品的通用模板

/** * 父类:基础饮品类 * 抽取所有饮品共有的属性和方法 */ public class BaseDrink { // 通用属性:所有饮品都有名称、价格、温度 private String name; private double price; private int temperature; // 通用方法:获取价格 public double getPrice() { return price; } public void setPrice(double price) { if(price < 0) { System.out.println("价格不能为负"); return; } this.price = price; } // 通用方法:饮用 public void drink() { System.out.println("饮用" + name + ",温度" + temperature + "度"); } // 通用get/set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getTemperature() { return temperature; } public void setTemperature(int temperature) { this.temperature = temperature; } }

再定义子类:奶茶类,继承基础饮品类

/** * 子类:奶茶类 * 继承BaseDrink,复用所有通用属性和方法,只需要补充奶茶独有的内容 */ public class MilkTea extends BaseDrink { // 子类独有属性:茶底 private String teaBase; // 子类独有方法:加小料 public void addTopping(String topping) { System.out.println("给" + getName() + "添加" + topping); } // 茶底的get/set public String getTeaBase() { return teaBase; } public void setTeaBase(String teaBase) { this.teaBase = teaBase; } }

👉 效果:MilkTea类里虽然只写了茶底和加小料的方法,但它自动拥有了父类BaseDrink的 name、price、temperature 属性,以及 drink、getPrice 等所有 public 方法,创建对象后可以直接调用:

public class Test { public static void main(String[] args) { MilkTea pearlTea = new MilkTea(); // 调用父类继承来的方法 pearlTea.setName("珍珠奶茶"); pearlTea.setPrice(12); pearlTea.setTemperature(60); // 调用子类自己的方法 pearlTea.setTeaBase("红茶"); pearlTea.addTopping("珍珠"); // 调用父类继承来的方法 pearlTea.drink(); } }

3. 子类到底能继承到什么?

继承不是父类所有内容都原封不动拿过来,能不能继承,完全由访问修饰符决定,和之前讲的权限规则完全对应:

父类成员的修饰符子类能否直接访问
public✅ 可以直接访问
protected✅ 可以直接访问(继承的核心设计之一)
default(包私有)同包子类可以,不同包子类不行
private❌ 不能直接访问

💡 补充:父类的 private 属性子类不是 “完全拿不到”,只是不能直接用this.属性名访问,依然可以通过父类提供的 public get/set 方法间接操作,这也是「封装 + 继承」配合的典型场景。


三、继承的核心规则与 super 关键字

1. Java 是单继承机制

Java 中一个子类只能有一个直接父类,不支持同时继承多个类(比如不能写class A extends B, C)。 但支持多层继承:A 继承 B,B 继承 C,A 会同时拥有 B 和 C 的所有可继承成员,形成「爷爷 → 爸爸 → 儿子」的继承树。 比如:BaseDrinkMilkTeaPearlMilkTea

2. 构造方法不能被继承

父类的构造方法,子类不能继承复用。但子类构造方法执行时,默认会先调用父类的无参构造方法,相当于先初始化父类的通用属性,再初始化子类的专属属性。 这个默认调用的动作,就是靠super()实现的。

3. super 关键字:父类对象的引用

super代表当前对象中父类部分的引用,专门用来访问父类的成员,和我们之前讲的this是对应关系。 它有三大核心用法,和this一一对应:

用法作用
super.属性名访问父类的成员变量
super.方法名(参数)调用父类的成员方法
super(参数)调用父类的构造方法
用法 1:调用父类构造方法

子类构造方法的第一行,默认会有一个隐藏的super();,自动调用父类的无参构造。 如果父类没有无参构造(比如手动写了有参构造),子类就必须手动用super(参数)调用父类的有参构造,否则编译报错。

代码示例:

// 父类:写了有参构造,没有无参构造 public class BaseDrink { private String name; private double price; public BaseDrink(String name, double price) { this.name = name; this.price = price; } } // 子类:必须手动调用父类有参构造 public class MilkTea extends BaseDrink { private String teaBase; public MilkTea(String name, double price, String teaBase) { // 必须写在第一行,调用父类有参构造,先初始化父类属性 super(name, price); this.teaBase = teaBase; } }

🔴 记忆:super(参数)this(参数)一样,都必须写在构造方法的第一行,所以二者不能同时出现在同一个构造方法里。

用法 2:调用父类的普通方法

子类重写父类方法后,如果还想用到父类原有的逻辑,可以用super.方法名()调用。 这个用法在方法重写里非常常用,下面讲重写的时候会结合示例。


四、方法重写(Override)

子类继承了父类的方法,但父类的通用逻辑不一定完全符合子类的需求,这时候子类可以重新实现父类的同名方法,这就是方法重写,也叫方法覆盖。

💡 通俗理解

父类的通用模板里写了「基础制作步骤」,但珍珠奶茶有自己的专属制作流程,就可以把制作方法重写一遍,保留通用部分,补充专属步骤,不用受父类逻辑的限制。

1. 重写的代码示例

// 父类 public class BaseDrink { public void make() { System.out.println("准备基础饮品原料"); } } // 子类重写make方法 public class MilkTea extends BaseDrink { // @Override 是注解,用来标记这是重写的方法,编译器会帮你检查格式是否正确 @Override public void make() { // 可以选择先调用父类的原有逻辑,也可以完全重写 super.make(); System.out.println("加入茶底和牛奶"); System.out.println("添加配料摇匀"); } }

2. 重写的核心规则(面试高频)

重写不是随便写个同名方法就行,必须遵守以下规则,否则就不是重写:

  1. 方法签名必须一致:方法名、参数列表、参数顺序必须和父类完全相同
  2. 返回值类型一致:基本类型必须相同,引用类型可以是父类返回值的子类
  3. 访问权限不能更严格:父类是 public,子类就不能写成 protected 或 private
  4. 抛出的异常不能更大:子类方法不能抛出比父类更宽泛的异常类型

3. 重写 vs 重载:别再混淆

很多不熟悉的同学容易把重写和重载搞混,二者完全不是一个维度的概念,对比表一目了然:

对比项方法重写(Override)方法重载(Overload)
适用场景父子类之间同一个类内部
方法签名必须完全一致方法名相同,参数列表必须不同
返回值必须一致(或子类)无要求
访问权限不能更严格无要求
核心作用子类重定义父类方法逻辑,实现运行时多态同一个方法名适配不同参数,提升易用性

🔴 记忆:一句话区分 —— 重写是父子类的 “覆盖”,重载是同个类的 “同名不同参”。


五、所有类的根父类:Object

Java 中有一个特殊的类:java.lang.Object,它是所有类的顶级父类。 哪怕你写类的时候没写extends,编译器也会默认让它继承 Object 类。也就是说,所有 Java 对象都拥有 Object 类中定义的方法,最常用的有三个:

  1. toString():把对象转成字符串表示
  2. equals():判断两个对象内容是否相等
  3. hashCode():返回对象的哈希值

这些方法所有类都能直接用,也可以根据需求重写,比如我们经常重写实体类的toString()equals()方法,就是继承自 Object 的重写应用。


六、不熟悉的同学容易踩的认知误区

误区 1:继承就是把父类的代码复制粘贴到子类里

✅ 正解:不是复制,是复用引用。子类对象里包含了一个完整的父类对象结构,二者是包含关系,不是复制关系,父类修改后所有子类都会同步生效。

误区 2:private 属性不能被继承,所以子类完全没有

✅ 正解:private 属性子类不能直接访问,但它依然存在于子类对象中,只是受封装保护,只能通过父类的 public 方法间接操作。

误区 3:继承越多、层级越深越好

✅ 正解:继承会增强类之间的耦合度 —— 父类修改会影响所有子类,层级过深会导致代码难以维护。 继承只适合真正的「is-a」关系(奶茶是饮品),不要为了单纯复用代码就强行用继承,复用代码还可以用组合、工具类等更灵活的方式。

误区 4:只要方法名一样就是重写

✅ 正解:必须满足参数列表、返回值、访问权限等所有规则才是重写,建议加上@Override注解,让编译器帮你校验格式,避免写错了自己还不知道。


七、和之前知识点的串联

  1. 关联封装:父类的私有属性靠封装隐藏,子类通过公共 get/set 方法间接访问,二者配合实现「内部数据保护 + 外部代码复用」。
  2. 关联访问修饰符protected权限就是专门为继承设计的 —— 让子类能访问父类成员,同时对外保持隐藏。
  3. 关联 this 关键字this指向当前对象本身,super指向当前对象的父类部分,二者配合完成对象内部的成员访问。
  4. 关联方法重载:重载是同类内的多同名方法,重写是父子类的方法覆盖,二者是完全不同的语法特性。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 4:13:08

百度输入法Linux版深度适配统信UOS技术解析

1. 项目背景与核心价值百度输入法Linux版登陆统信UOS社区版应用商店&#xff0c;标志着国产操作系统生态建设取得实质性进展。作为国内首个适配统信UOS的商业输入法&#xff0c;这个版本针对Linux桌面环境进行了深度优化&#xff0c;解决了长期以来Linux用户面临的中文输入体验…

作者头像 李华
网站建设 2026/7/17 4:12:12

Python数据科学核心工具链与实战技巧详解

1. Python数据科学手册概述《Python数据科学手册》是一本面向数据科学实践者的工具书&#xff0c;它系统性地介绍了如何利用Python生态中的核心工具链完成数据科学全流程工作。不同于传统编程教材&#xff0c;这本书聚焦于数据科学特有的技术栈和工作模式&#xff0c;从数据获取…

作者头像 李华
网站建设 2026/7/17 4:11:55

华为MetaERP 跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一。Oracle EBS原生并未提供直接的“供应商地点→库存组织”映射表,这需要在扩展层自行设计。下面给出经过生产

跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一。Oracle EBS原生并未提供直接的“供应商地点→库存组织”映射表&#xff0c;这需要在扩展层自行设计。下面给出经过生产验证的配置表设计方案。跨OU的供应商地点与库存组织映射是P2P多OU架构设计的核心难点之一…

作者头像 李华
网站建设 2026/7/17 4:09:42

Action Token设计:VLA模型与物理世界的神经接口

1. 为什么“Action Token”不是简单切分动作数据就能搞定的事VLA——Vision-Language-Action&#xff0c;这个缩写最近在具身智能圈里几乎天天刷屏。但真正动手做过VLA模型训练的人会发现&#xff1a;视觉编码器可以套CLIP&#xff0c;语言部分能直接搬Llama&#xff0c;可一到…

作者头像 李华
网站建设 2026/7/17 4:08:39

世界行动模型WAM与VLA范式对比:泛化能力的四个刚性维度

1. 问题的起点&#xff1a;当“世界行动模型”突然闯入视觉语言领域最近在几个主流AI顶会的workshop讨论区、arxiv每日推送和实验室组会上&#xff0c;频繁看到一个新词组合——“世界行动模型”&#xff08;World Action Model, WAM&#xff09;。它不像VLA&#xff08;Vision…

作者头像 李华
网站建设 2026/7/17 4:08:36

AI模型训练全流程实战:从数据准备到生产部署

1. 初学者AI模型训练全景指南AI模型训练正从实验室走向大众视野&#xff0c;去年斯坦福大学的研究显示&#xff0c;当训练数据错误率超过5%时&#xff0c;即使是顶尖模型的性能也会断崖式下跌。这个数字提醒我们&#xff1a;数据质量与训练方法同等重要。作为从传统软件开发转型…

作者头像 李华