Java 中的继承与多态:面向对象编程的核心特性

news2025/4/3 7:55:29

继承和多态是面向对象编程中最重要的两个概念,它们使代码结构更加清晰、灵活,并极大地提高了代码复用性。本文将深入探讨 Java 中的继承与多态,帮助你更好地理解这些核心概念。

1. 继承

1.1 为什么需要继承

在实际编程中,我们经常会遇到不同的类具有相似的属性和行为。例如,猫和狗都是动物,它们都有名字、年龄等属性,也都有吃饭、睡觉等行为。如果为每一个类都独立编写这些共同的属性和方法,会导致代码重复,维护困难。
继承机制允许我们定义一个通用的基类(父类),然后创建从这个基类派生的子类。子类继承父类的属性和方法,同时可以添加自己特有的属性和方法。

1.2 继承的语法

Java 中使用 extends 关键字表示继承关系:

// 父类
public class Animal {
    String name;
    int age;
    
    public void eat() {
        System.out.println(name + "正在吃饭");
    }
    
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

// 子类
public class Dog extends Animal {
    public void bark() {
        System.out.println(name + "汪汪汪~~~");
    }
}

// 子类
public class Cat extends Animal {
    public void mew() {
        System.out.println(name + "喵喵喵~~~");
    }
}

1.3 成员访问规则

在继承关系中,子类访问父类成员的规则如下:

成员变量:
如果子类和父类中的成员变量不同名,子类可以直接访问父类的成员变量
如果同名,子类优先访问自己的成员变量
如果需要访问被覆盖的父类成员变量,可以使用 super 关键字

成员方法:
如果方法名不同,子类可以直接调用父类的方法
如果方法名相同但参数不同(构成重载),根据调用时的参数确定调用哪个方法
如果方法签名完全相同(构成重写),子类方法会覆盖父类方法,如果需要调用父类的被覆盖方法,需使用 super 关键字

1.4 super 关键字

super 关键字用于在子类中访问父类的成员:

public class Derived extends Base {
    int a; // 与父类同名
    
    public void method() {
        a = 100;         // 访问子类自己的 a
        super.a = 200;   // 访问父类的 a
        
        methodB();       // 调用子类自己的方法
        super.methodB(); // 调用父类的方法
    }
}

1.5 构造方法继承

在创建子类对象时,必须先调用父类的构造方法,再执行子类的构造方法。如果没有显式调用父类构造方法,Java 会自动插入对父类无参构造方法的调用:

public class Derived extends Base {
    public Derived() {
        // 编译器自动插入 super();
        System.out.println("Derived()");
    }
}

特别注意:

子类构造方法中调用父类构造方法必须是第一条语句
子类可以通过 super(参数) 显式调用父类的特定构造方法

2. 组合

组合是另一种代码复用的方式,它表示"has-a"关系,通过将一个类的对象作为另一个类的成员变量来实现:

class Tire { }
class Engine { }

class Car {
    private Tire tire;       // 汽车有轮胎
    private Engine engine;   // 汽车有发动机
}

与继承相比,组合的耦合性较低,更灵活。一般建议:能用组合尽量用组合。

3. 多态

3.1 多态的概念

多态是指同一个行为,作用于不同的对象,会产生不同的结果。在面向对象编程中,多态使程序更加灵活和可扩展。

3.2 多态的实现条件

Java 中实现多态需要满足三个条件:

必须在继承体系下
子类必须重写父类的方法
通过父类引用调用重写的方法

3.3 方法重写

方法重写是子类对父类方法的重新实现。重写时需要遵循以下规则:

方法名、参数列表必须相同
返回类型可以相同,或是父类返回类型的子类型
访问权限不能比父类更严格
不能抛出比父类方法更多的异常

3.4 向上转型和向下转型

向上转型是将子类对象赋值给父类引用:

Animal animal = new Dog(); // 向上转型

向下转型是将父类引用转换为子类引用:

Dog dog = (Dog)animal; // 向下转型,需要类型转换

向下转型可能不安全,应该使用 instanceof 操作符进行类型检查:

if (animal instanceof Dog) {
    Dog dog = (Dog)animal;
    dog.bark();
}

3.5 多态的优缺点

优点:
降低代码的"圈复杂度",避免大量的 if-else 语句
提高代码的可扩展性,增加新的子类时无需修改调用代码

缺点:
多态会有一定的性能开销
不能访问子类特有的方法(除非向下转型)
属性没有多态性,只能访问父类属性

3.6 避免在构造方法中调用重写的方法

在构造方法中调用可能被子类重写的方法很危险,因为当创建子类对象时,父类构造方法会在子类字段初始化之前执行,可能导致未预期的结果。

结论

继承和多态是 Java 面向对象编程的核心概念,掌握它们对于编写出高质量的代码至关重要。继承提供了代码复用的机制,而多态则提供了灵活性和可扩展性。然而,我们也应当注意继承的一些局限性,**例如 Java 不支持多继承,以及继承可能导致较高的耦合度。**在实际开发中,应当根据具体情况选择使用继承还是组合。

记住这句面向对象设计的经典建议:“组合优于继承”。在大多数情况下,组合会提供更好的灵活性和更低的耦合度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2326401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可编程增益放大器(PGA)在智能传感器自调节系统中的角色

在电子电路设计中,放大器芯片作为信号处理的核心器件,其性能直接影响系统整体表现。然而面对运算放大器、功率放大器、仪表放大器等众多类型,工程师常陷入选型困惑。作为国内领先的半导体解决方案提供商,华芯邦深耕放大器芯片领域…

微信登录、商品浏览前瞻

一.业务效果 二.所需技术

浙大研究团队揭示电场调控5-HT1AR的分子机制

本期介绍的文章题为 “Structural Insight into the Inactive/Active States of 5‑HT1AR and Molecular Mechanisms of Electric Fields in Modulating 5‑HT1AR” 。近期发表于JCIM。通过分子动力学模拟,探究 5-羟色胺 1A 受体(5-HT1AR) 在非活性 / 活性状态的构象…

视频AI赋能水利行业生态治理,水电站大坝漂浮物实时监测与智能预警方案

水电站大坝周边水域垃圾漂浮物不仅影响水质,还可能对大坝设施运行、水生态环境造成威胁。传统依靠人工巡检的方式效率低、存在监测盲区,难以实时全面地掌握漂浮物情况。借助EasyCVR视频汇聚平台与TSINGSEE青犀AI算法中台构建智能化监测方案,能…

flink 分组窗口聚合 与 窗口表值函数聚合 的区别

警告:分组窗口聚合已经过时。推荐使用更加强大和有效的窗口表值函数聚合。 参考官方文档 在 Apache Flink 中,分组窗口聚合(Group Window Aggregation) 和 窗口表值函数聚合(Windowing TVF Aggregation)…

阿里云Tair KVCache:打造以缓存为中心的大模型Token超级工厂

一、Tair KVCache 简介 Tair KVCache 是阿里云瑶池旗下云数据库 Tair 面向大语言模型推理场景推出的 KVCache 缓存加速服务。 随着互联网技术的演进与流量规模的激增,缓存技术逐渐成为系统架构的核心组件。该阶段催生了 Redis 等开源缓存数据库,阿里巴巴…

通过TIM+DMA Burst 实现STM32输出变频且不同脉冲数量的PWM波形

Burst介绍: DMA控制器可以生成单次传输或增量突发传输,传输的节拍数为4、8或16。 为了确保数据一致性,构成突发传输的每组传输都是不可分割的:AHB传输被锁定,AHB总线矩阵的仲裁器在突发传输序列期间不会撤销DMA主设备…

[Effective C++]条款26:尽可能延后变量定义的出现时间

. 在C中,尽可能延后变量定义的出现时间,主要原因是为了提供代码的可读性,减少不必要的开销以及避免潜在的错误。 1、代码执行过程中抛出异常 如果在代码开头定义了变量,但在后续代码中抛出了异常,可能导致变量在未被使…

如何在k8s中对接s3存储

github地址: https://github.com/majst01/csi-driver-s3 1.CSI for S3 这是用于 S3(或兼容 S3)存储的容器存储接口 (CSI)。它可以动态分配存储桶并通过Fuse mount将它们安装到任何容器中 2.状态 这仍处于试验阶段,不应在任何…

FPGA实现LED流水灯

一、在VsCode中写代码 1、建立工程项目文件water_led.v文件 2、打开项目文件,创建三个目录 3、打开文件trl,创建water_led.v文件 4、打开文件tb,创建water_led_tb.v文件 5、用VsCode打开water_led.v文件,编写源代码 module water…

百度文库免费下载器

01 引言 在国内的环境下,Greasy Fork网站是彻底打不开了,导致好多小伙伴想要用脚本都没办法。 特别是需要某Wen库下载的小伙伴,之前还说实在没办法,去Greasy Fork网站上安个脚本就可下载,但是现在网站被墙了&#xf…

[NCTF2019]True XML cookbook[XXE] [内网探测] [网络ip相关知识]

一模一样的登录界面 我直接故伎重演但是并卵 &#xff08;话说XXE注入之前好像其他博客都加上了<?xml version"1.0" encoding"utf-8"?>&#xff0c;但是不加好像也没有什么问题&#x1f914;&#xff09; <?php /** * autor: c0ny1 * date: …

Linux驱动的基本概念

一 交叉开发编译 概念&#xff1a;交叉开发编译(Cross Compilation)是指在一个平台上生成能在另一个不同平台上执行的代码的编译过程。这是嵌入式系统开发和跨平台软件开发中的常见技术。 二 系统启动流程 在Linux源码下&#xff0c;通过网口利用tftp协议把u-bantu下的uImage…

win server2022 限制共享文件夹d

点击配额管理中的配额 然后创建配额 导入要配额的文件即可 然后确定即可

Ansible(3)——主机清单与配置文件

目录 一、创建 Ansible 清单&#xff1a; 1、清单定义&#xff1a; 2、使用静态清单指定受管主机&#xff1a; &#xff08;1&#xff09;主机名称指定&#xff1a; &#xff08;2&#xff09;IP 地址指定&#xff1a; 3、验证清单&#xff1a; &#xff08;1&#xff0…

C语言 【初始指针】【指针一】

引言 思绪很久&#xff0c;还是决定写一写指针&#xff0c;指针这块内容很多&#xff0c;也不是那么容易说清楚&#xff0c;这里尽可能写地详细&#xff0c;让大家理解指针。&#xff08;未完序&#xff09; 一、内存和地址 在讲指针前&#xff0c;需要有一个对内存和地址的认…

IP 地址规划中的子网划分:/18 网络容纳 64 个 C 段(/24)的原理与应用解析

整体表格说明 这是某市教育城域网中某县教育相关机构的IP地址规划表&#xff0c;明确了某县一中和某县教育局的IP地址范围&#xff0c;包括终端使用地址段、业务互访地址段。 概念解析 64个C段终端及互联地址 C段地址&#xff1a;一个C段是IP地址中的一个/24网络&#xff08;…

linux下Tomcat配置提示权限不够解决办法

文章目录 前言解决方案 前言 往linux服务器上部署Java后端&#xff0c;但是在服务器上安装好的tomcat&#xff0c;却因为权限不够无法进入 这就导致后端war包项目及前端页面无法部署 解决方案 sudo chmod -R 777 /opt/tomcat/webapps修改tomcat目录下的权限即可&#xff0c;对…

您使用的开源软件许可证是否存在冲突呢?

开源软件代码使用现状 根据最新发布的《第三次自由和开源软件普查报告》&#xff0c;96%的代码库中使用了开源组件&#xff0c;这表明开源技术在现代软件开发中占据了核心地位。在国内企业软件项目中&#xff0c;开源软件的使用率达到了100%&#xff0c;平均每个项目使用了166…

leetcode刷题日记——接雨水

[ 题目描述 ]&#xff1a; [ 思路 ]&#xff1a; 题目要求求凹进去的部分能接多少雨水&#xff0c;即有多少个格子可以从第一个高度快出发去寻找下一个高于或者等于他的格子&#xff0c;然后计算其中的差值 有高于或等于他的格子&#xff0c;计算他俩中间能装的雨水当后续没有…