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

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.xdnf.cn/news/15735.html

相关文章:

  • 基于GEE与哨兵2号的土地覆盖分类方法及实现
  • Vue Swiper组件
  • n8n教程分享,从Github读取.md文档内容
  • MySQL(145)如何升级MySQL版本?
  • 【爬虫】04 - 高级数据存储
  • Fortran实战:快速解析气象NC数据
  • OpenCV 官翻8 - 其他算法
  • 牛客-倒置字符串
  • SQL Server和PostgreSQL填充因子
  • debian的pulseaudio删掉也没事
  • SIMATIC WinCC Unified 使用 KPI 优化流程
  • Nacos配置管理
  • 【Unity3D实例-功能-移动】角色移动-通过WSAD(Rigidbody方式)
  • Kafka、RabbitMQ 与 RocketMQ 高可靠消息保障方案对比分析
  • TinyMCE 富文本编辑器在 vue2 中的使用 @tinymce/tinymce-vue
  • MySQL——约束类型
  • Vue 3 中封装并使用 IndexedDB 的完整教程(含泛型、模块化、通用 CRUD)
  • 网络爬虫概念初解
  • 【Unity】YooAsset问题记录
  • 如何在HTML5页面中嵌入视频
  • Git基础
  • 【每日算法】专题十五_BFS 解决 FloodFill 算法
  • 电脑windows系统深度维护指南
  • 微软原版系统下载的几个好用网站
  • [牛客2020提高赛前集训营day3] 牛半仙的魔塔
  • 在服务器(ECS)部署 MySQL 操作流程
  • Window延迟更新10000天配置方案
  • QML 动画效果详解
  • 巧用Callbre RVE生成DRC HTML report及CTO的使用方法
  • 从五次方程到计算机:数学抽象如何塑造现代计算