当前位置: 首页 > news >正文

Java 中的继承与多态

在 Java 面向对象编程中,继承和多态是两大核心特性,它们不仅能帮助我们实现代码复用,还能让程序更具灵活性和可扩展性。下面我们将详细探讨这两个概念。

一.继承:实现代码复用的利器

1.1为什么需要继承

在现实世界中,许多事物之间存在关联,比如狗和猫都属于动物,它们具有一些共同的属性(如名字、年龄)和行为(如吃饭、睡觉)。在 Java 中用类描述这些事物时,如果分别为狗和猫创建类,会出现大量重复的代码。继承机制正是为了解决这一问题,它可以将这些共性内容抽取出来,实现代码的复用。

1.2继承的概念与语法

继承是面向对象编程中实现代码复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,生成新的类(派生类)。在 Java 中,通过extends关键字来表示类之间的继承关系,语法格式为:

修饰符 class 子类 extends 父类 {// ...
}

其中,被继承的类称为父类(基类或超类),继承父类的类称为子类(派生类)。子类可以复用父类中的成员,同时还能添加自己特有的成员。

1.3父类成员的访问规则

  • 成员变量:在子类方法中访问成员变量时,遵循就近原则。如果子类中有该成员变量,优先访问子类的;如果没有,则访问父类继承下来的;若父类也没有,则编译报错。
  • 成员方法:当成员方法名字不同时,在子类中优先访问自己的方法,自己没有时再到父类中找;当方法名字相同时,若参数列表不同(重载),根据参数选择合适的方法;若参数列表相同,则优先访问子类的方法(重写)。

当需要在子类中明确访问父类的成员时,可以使用super关键字。

super关键字:

如果必须要访问和父类同名的方法,我们可以使用父类来访问。
Super.data访问父类的成员变量  Super.func()访问父类的成员方法
super只能指代 当前类的父类不能指代 父类的父类 .

1.4子类构造方法

子类对象构造时,需要先调用父类的构造方法,然后再执行子类的构造方法,即 “先有父再有子”。如果父类显式定义了无参或默认的构造方法,子类构造方法第一行会默认隐含super()调用;如果父类构造方法带有参数,子类需要显式定义构造方法并调用合适的父类构造方法,且super(...)必须是子类构造方法中的第一条语句,只能出现一次,不能与this同时出现。

例如:

 public static void main(String[] args) {class Base {private int x;private int y;public Base(int x, int y) {this.x = x;this.y = y;}}class Sub extends Base {private int z;public Sub(int x, int y, int z) {super(x, y);this.z = z;}}

1.5super 与 this 的对比

相同点不同点
都是 Java 关键字;只能在非静态方法中使用;在构造方法中调用时必须是第一条语句且不能同时存在this是当前对象的引用,用于访问本类的成员和方法;super是子类对象中从父类继承下来部分成员的引用,用于访问父类的成员和方法

1.6初始化顺序

在继承关系中,初始化顺序为:父类静态代码块→子类静态代码块→父类实例代码块→父类构造方法→子类实例代码块→子类构造方法。其中,静态代码块只在类加载阶段执行一次。

1.7继承方式

  • 继承方式:Java 支持单继承、多层继承和不同类继承同一个类,但不支持多继承。
  • final 关键字final可修饰变量(表示常量,不能修改)、类(表示此类不能被继承)和方法(表示该方法不能被重写)。

1.8继承与组合

继承体现的是 “A是B” 的关系(如狗是动物),组合体现的是 “A有B” 的关系(如汽车有发动机)。两者都能实现代码复用,一般建议能用组合尽量用组合。

组合例子:

class Heart {public void beat() {System.out.println("心脏跳动");}
}class Person {private Heart heart; // 人包含心脏的引用public Person() {this.heart = new Heart(); // 创建人时初始化心脏}public void live() {heart.beat(); // 人通过心脏跳动维持生命}
}

  1. Person 类在内部维护了一个 Heart 对象的引用。
  2. Heart 对象在 Person 的构造函数中被创建,其生命周期与 Person 实例绑定。
  3. 当 Person 对象被销毁时,Heart 对象也会随之被销毁。
  4. Person 通过调用 heart.beat() 方法来使用其内部组件的功能。

二.多态:灵活多样的行为表现

2.1多态的概念

多态指的是完成某个行为时,不同的对象去完成会产生不同的状态,即 “同一件事情,发生在不同对象身上,会产生不同的结果”。

2.2多态的实现条件

要实现多态,必须满足以下三个条件:

  1. 存在继承体系;
  2. 子类对父类中的方法进行重写;
  3. 通过父类的引用调用重写的方法。

2.3方法重写

重写(override)是子类对父类非静态、非private修饰、非final修饰、非构造方法的实现过程进行重新编写,要求返回值类型、方法名和参数列表完全一致(返回值类型可以是具有父子关系的)。重写时,子类方法的访问权限不能比父类中被重写的方法的访问权限更低,可使用@Override注解进行合法性校验。

重写与重载的区别如下:

区别点重写(override)重载(overload)
参数列表一定不能修改必须修改
返回类型一定不能修改(除非具有父子关系)可以修改
访问限定符不能做更严格的限制(可以降低限制)可以修改

2.4向上转型与向下转型

  • 向上转型:创建一个子类对象,将其当成父类对象来使用,语法为 “父类类型 对象名 = new 子类类型 ()”。它能让代码更简单灵活,但不能调用子类特有的方法。
  • 向下转型:将经过向上转型的父类引用还原为子类对象,需要强制转换。这种操作不安全,可能会抛出ClassCastException,可使用instanceof关键字先判断,再进行转换以提高安全性。

2.5多态的优缺点

  • 优点:能降低代码的 “圈复杂度”,避免使用大量的if-else语句;可扩展能力更强,新增子类时无需修改原有代码。
  • 缺点:代码的运行效率降低;属性没有多态性,通过父类引用只能访问父类的成员属性;构造方法没有多态性。

注意事项

应避免在构造方法中调用被重写的方法,因为此时子类对象还未构造完成,可能会出现隐藏的问题。

http://www.lryc.cn/news/593481.html

相关文章:

  • 5.组合模式
  • 3.5软件开发活动[2-系统设计]面向对象设计-UML统一开发过程
  • [故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型
  • 在Vscode中使用Kimi K2模型:实践指南,三分钟生成个小游戏
  • 练习三:熟知前端知识
  • 目标检测中的标签分配算法总结
  • MinIO深度解析:从核心特性到Spring Boot实战集成
  • Vue的路由模式的区别和原理
  • 《Qt5串口开发》搭建跨平台通信系统
  • VSCode用Python操作MySQL:环境配置与代码验证
  • 操作系统-分布式同步
  • 实验室危险品智能管控:行为识别算法降低爆炸风险
  • Mybatis学习之简介(一)
  • Vue 3 中封装并使用 IndexedDB 的完整教程(含泛型、模块化、通用 CRUD)
  • Vue Swiper组件
  • 93.数字信号处理相关的一些问题
  • 单元测试学习+AI辅助单测
  • 【ArcGIS技巧】最近分享的GIS插件总结与优化
  • Spring MVC源码分析 DispatcherServlet#getHandlerAdapter方法
  • LVS四种工作模式深度解析
  • Go 语言核心机制深度剖析:指针、defer、多态与空接口实战指南
  • 使用 go-redis-entraid 实现 Entra ID 无密钥认证
  • Go-Redis × RediSearch 全流程实践
  • leetcode_121 买卖股票的最佳时期
  • 力扣经典算法篇-26-长度最小的子数组(暴力求解法,左右指针法)
  • 【Java】【力扣】48.旋转图像
  • FPGA自学——整体设计思路
  • Redis数据库基础与持久化部署
  • 使用CCS6.2为C2000(DSP28335)生成.bin文件和.hex文件
  • 【LeetCode 热题 100】437. 路径总和 III——(解法一)递归递归!