Java 中的 super 关键字

news2025/5/28 23:09:45

个人总结:

1.子类构造方法中没有显式使用super,Java 也会默认调用父类的无参构造方法

2.当父类中没有无参构造方法,只有有参构造方法时,子类构造方法就必须显式地使用super来调用父类的有参构造方法。

3.如果父类没有定义任何构造方法,编译器会自动为父类生成一个无参构造方法。但如果父类已经定义了有参构造方法,编译器不会自动生成无参构造方法,此时子类必须显式调用父类的有参构造方法

在 Java 的面向对象编程世界里,继承是一个极为重要的特性,它让代码得以复用和扩展,构建出层次分明的类体系。而super关键字,就像是一把神奇的钥匙,在继承的场景中发挥着不可或缺的作用。它能够帮助我们轻松访问父类的成员,理解和掌握super关键字,对于编写高效、健壮的 Java 代码至关重要。接下来,我们就深入探究一下super关键字的奥秘。​

一、super 关键字的基本概念​

super是 Java 中的一个关键字,它主要用于在子类中访问父类的成员,包括成员变量、成员方法以及构造方法 。需要明确的是,super代表的是对当前对象父类对象的引用,但它并不像普通对象引用那样可以随意使用,它有着特定的使用场景和规则。​

二、super 调用父类构造方法​

在类的继承关系中,当创建子类对象时,会先调用父类的构造方法,然后再调用子类自身的构造方法,这是 Java 对象初始化的一个重要机制。而super关键字可以在子类构造方法中显式地调用父类的构造方法。​

1. 无参构造方法调用​

先来看一个简单的例子,定义一个父类Animal:

class Animal {
    public Animal() {
        System.out.println("Animal类的无参构造方法被调用");
    }
}

再定义一个子类Dog继承自Animal:

class Dog extends Animal {
    public Dog() {
        System.out.println("Dog类的无参构造方法被调用");
    }
}

在测试类中创建Dog对象:

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}

运行结果为:

Animal类的无参构造方法被调用
Dog类的无参构造方法被调用

可以看到,在创建Dog对象时,即使子类构造方法中没有显式使用super,Java 也会默认调用父类的无参构造方法。这是 Java 的一个隐式规则,目的是确保父类对象先完成初始化,为子类对象的初始化提供基础。

2. 有参构造方法调用​

当父类中没有无参构造方法,只有有参构造方法时,子类构造方法就必须显式地使用super来调用父类的有参构造方法。例如,修改Animal类:

class Animal {
    private String name;
    public Animal(String name) {
        this.name = name;
        System.out.println("Animal类的有参构造方法被调用,动物名称:" + name);
    }
}

然后修改Dog类的构造方法:

class Dog extends Animal {
    public Dog(String name) {
        super(name);
        System.out.println("Dog类的有参构造方法被调用");
    }
}

测试代码如下:

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("旺财");
    }
}

运行结果:

Animal类的有参构造方法被调用,动物名称:旺财
Dog类的有参构造方法被调用

在子类Dog的构造方法中,super(name)这行代码明确指定了调用父类Animal的有参构造方法,并将参数传递过去,这样才能正确完成对象的初始化过程。同时要注意,super调用父类构造方法的语句必须是子类构造方法的第一行代码 ,否则会编译报错。​

三、super 访问父类成员变量​

当子类中定义了与父类同名的成员变量时,如果在子类中直接访问该变量名,默认访问的是子类自身的成员变量。此时,如果想要访问父类的同名成员变量,就可以使用super关键字。​

定义父类Person:

class Person {
    String name = "父类的姓名";
}

定义子类Student继承自Person:

class Student extends Person {
    String name = "子类的姓名";
    public void printNames() {
        System.out.println("子类的name:" + name);
        System.out.println("父类的name:" + super.name);
    }
}

测试代码:

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.printNames();
    }
}

运行结果:

子类的name:子类的姓名
父类的name:父类的姓名

通过super.name,我们在子类Student中成功访问到了父类Person的成员变量name,避免了变量访问的混淆。​

四、super 调用父类成员方法​

同样,当子类重写了父类的方法时,如果在子类中想要调用父类被重写的方法,也可以借助super关键字。​

定义父类Vehicle:

class Vehicle {
    public void run() {
        System.out.println("车辆在行驶");
    }
}

定义子类Car继承自Vehicle并重写run方法:

class Car extends Vehicle {
    @Override
    public void run() {
        super.run();
        System.out.println("汽车在马路上快速行驶");
    }
}

测试代码:

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.run();
    }
}

运行结果:

车辆在行驶
汽车在马路上快速行驶

在子类Car的run方法中,super.run()调用了父类Vehicle的run方法,这样既保留了父类方法的功能,又在其基础上进行了扩展,实现了代码的复用和增强。

五、父类定义有参、无参构造方法的各种情况

在 Java 中,如果父类没有定义任何构造方法,编译器会自动为父类生成一个无参构造方法。但如果父类已经定义了有参构造方法,编译器不会自动生成无参构造方法,此时子类必须显式调用父类的有参构造方法

1.关键规则总结:

父类情况子类构造方法中是否显式调用super()结果
有无参构造方法未显式调用super()编译器自动插入super();(调用父类无参构造)
有参构造方法但没有无参构造方法未显式调用super()❌ 编译错误:找不到父类的无参构造方法
有参构造方法但没有无参构造方法显式调用super(参数);✅ 正确:调用父类的有参构造方法

2.示例代码分析

父类没有定义任何构造方法

class Parent {
    // 编译器会自动添加无参构造方法:
    // public Parent() {}
}

class Child extends Parent {
    public Child() {
        // 编译器会自动插入 super();
    }
}

父类只有有参构造方法

class Parent {
    public Parent(int value) { // 定义了有参构造方法
        // ...
    }
    // 注意:编译器不会自动生成无参构造方法!
}

class Child extends Parent {
    public Child() {
        // ❌ 编译错误:没有super(),但父类没有无参构造方法
    }
    
    public Child(int value) {
        super(value); // ✅ 必须显式调用父类的有参构造方法
    }
}

3. 常见错误案例

以下代码会导致编译错误:

class Animal {
    private String name;
    
    public Animal(String name) { // 父类只有有参构造
        this.name = name;
    }
}

class Dog extends Animal {
    public Dog() {
        // ❌ 编译错误:没有super(),但父类没有无参构造
    }
}

修正方式:在子类构造方法中显式调用父类的有参构造方法

class Dog extends Animal {
    public Dog(String name) {
        super(name); // ✅ 显式调用父类的有参构造
    }
}

六、super( )详解

1.super() 是什么?

在 Java 中,super()子类构造方法中调用父类构造方法的特殊语法。它必须是子类构造方法的第一行代码。

2.为什么需要 super()

当创建子类对象时,Java 会先初始化父类的部分。通过super(),我们可以显式指定如何初始化父类的状态。

3.最简单的示例

下面是一个基础示例,展示super()的基本用法:

// 父类:动物
class Animal {
    private String name;

    // 父类的构造方法
    public Animal(String name) {
        this.name = name;
        System.out.println("创建了一只动物:" + name);
    }

    public String getName() {
        return name;
    }
}

// 子类:狗
class Dog extends Animal {
    private String breed;

    // 子类的构造方法
    public Dog(String name, String breed) {
        super(name); // 调用父类的构造方法,必须在第一行
        this.breed = breed;
        System.out.println("这是一只" + breed + ":" + name);
    }

    public String getBreed() {
        return breed;
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("旺财", "金毛");
        System.out.println(dog.getName() + "是一只" + dog.getBreed());
    }
}    

4.关键代码解释

父类构造方法

public Animal(String name) {
    this.name = name;
}

Animal类的构造方法接收一个name参数,用于初始化动物的名称。

子类构造方法中的super()

public Dog(String name, String breed) {
    super(name); // 调用父类构造方法,初始化name
    this.breed = breed; // 初始化子类特有的属性
}

super(name)name参数传递给父类的构造方法,确保父类的name字段被正确初始化。

如果省略super(name),Java 会默认调用父类的无参构造方法(如果存在)。

5.执行流程

当执行Dog dog = new Dog("旺财", "金毛");时:

  1. 调用子类构造方法Dog(String name, String breed)
  2. 隐式 / 显式调用父类构造方法
    • 通过super(name)调用Animal(String name)
  3. 父类初始化完成Animalname字段被设置为 "旺财"
  4. 继续执行子类构造方法this.breed = breedbreed设置为 "金毛"

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

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

相关文章

PCM音频数据的编解码

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据 总结 前言 提示:这里可以添加本文要记录的大概内容: 例如&#xff1a…

Ubuntu 通过指令远程命令行配置WiFi连接

前提设备已经安装了无线网卡。 1、先通过命令行 ssh 登录机器。 2、搜索wifi设备,指令如下: sudo nmcli device wifi 3、输入需要联接的 wifi 名称和对应的wifi密码,指令如下: sudo nmcli device wifi connect wifi名称 passw…

8天Python从入门到精通【itheima】-41~44

目录 41节-while循环的嵌套应用 1.学习目标 2.while循环的伪代码和生活情境中的应用 3.图片应用的代码案例 4.代码实例【Patrick自己亲手写的】: 5.whlie嵌套循环的注意点 6.小节总结 42节-while循环的嵌套案例-九九乘法表 1.补充知识-print的不换行 2.补充…

深度图数据增强方案-随机增加ROI区域的深度

主要思想:随机增加ROI区域的深度,模拟物体处在不同位置的形态。 首先打印一张深度图中的深度信息分布: import cv2 import matplotlib.pyplot as plt import numpy as np import seaborn as sns def plot_grayscale_histogram(image_path)…

两个mysql的maven依赖要用哪个?

背景 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> </dependency>和 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId> &l…

Kafka Consumer工作流程

Kafka Consumer工作流程图 1、启动与加入组 消费者启动后&#xff0c;会向 Kafka 集群中的某个 Broker 发送请求&#xff0c;请求加入特定消费者组。这个 Broker 中的消费者协调器&#xff08;Consumer Coordinator&#xff09;负责管理消费者组相关事宜。 2、组内分区分配&am…

大腾智能 PDM 系统:全生命周期管理重塑制造企业数字化转型路径

在当今激烈的市场竞争中&#xff0c;产品迭代速度与质量已成为企业生存与发展的核心命脉。面对客户需求多元化、供应链协同复杂化、研发成本管控精细化等挑战&#xff0c;企业亟需一套能够贯穿产品全生命周期的数字化解决方案。 大腾智能PDM系统通过构建覆盖设计、研发、生产、…

【短距离通信】【WiFi】WiFi7关键技术之4096-QAM、MRU

目录 3. 4096-QAM 3.1 4096-QAM 3.2 QAM 的阶数越高越好吗&#xff1f; 4. MRU 4.1 OFDMA 和 RU 4.2 MRU 资源分配 3. 4096-QAM 摘要 本章主要介绍了Wi-Fi 7引入的4096-QAM对数据传输速率的提升。 3.1 4096-QAM 对速率的提升 Wi-Fi 标准一直致力于提升数据传输速率&a…

线程池实战——数据库连接池

引言 作者在前面写了很多并发编程知识深度探索系列文章&#xff0c;反馈得知友友们收获颇丰&#xff0c;同时我也了解到友友们也有了对知识如何应用感到很模糊的问题。所以作者就打算写一个实战系列文章&#xff0c;让友友们切身感受一下怎么应用知识。话不多说&#xff0c;开…

基于moonshot模型的Dify大语言模型应用开发核心场景

基于moonshot模型的Dify大语言模型应用开发核心场景学习总结 一、Dify环境部署 1.Docker环境部署 这里使用vagrant部署&#xff0c;下载vagrant之后&#xff0c;vagrant up登陆&#xff0c;vagrant ssh&#xff0c;在vagrant 中使用 vagrant centos/7 init 快速创建虚拟机 安装…

华为OD机试真题——字符串序列判定(2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

工商总局可视化模版-Echarts的纯HTML源码

概述 基于ECharts的工商总局数据可视化HTML模版&#xff0c;帮助开发者快速搭建专业级工商广告数据展示平台。这款模版设计规范&#xff0c;功能完善&#xff0c;适合各类工商监管场景使用。 主要内容 本套模版采用现代化设计风格&#xff0c;主要包含以下核心功能模块&…

Spring AI 和 Elasticsearch 作为你的向量数据库

作者&#xff1a;来自 Elastic Josh Long, Philipp Krenn 及 Laura Trotta 使用 Spring AI 和 Elasticsearch 构建一个完整的 AI 应用程序。 Elasticsearch 原生集成了业界领先的生成式 AI 工具和服务提供商。查看我们关于超越 RAG 基础或使用 Elastic 向量数据库构建生产级应用…

集群聊天服务器学习 配置开发环境(VScode远程连接虚拟机Linux开发)(2)

配置远程开发环境 第一步&#xff1a;Linux系统运行sshd服务 第二步&#xff1a;在vscode上安装Remote Deve I opment插件&#xff0c;其依赖插件会自动安装 第三步&#xff1a;配置远程Linux主机的信息 第四步&#xff1a;在vscode上开发远程连接Linux 第一步&#xff1a;…

rabbitmq的使用介绍

一.队列工作模式介绍 1.WorkQueues模型 生产者直接把消息发送给队列&#xff0c;然后消费者订阅队列 特点: 消息不会重复, 分配给不同的消费者. 代码实现&#xff1a; 消费者代码&#xff1a; Component Slf4j public class SpringRabbitListener {RabbitListener(queues &q…

系统编程day04

一.进程的基本概念 一.定义 进程是一个程序执行的过程&#xff08;也可以说是正在运行的程序&#xff09;&#xff0c;是系统分配资源的基本单位&#xff0c;由cpu对各个进程指挥调度&#xff0c;在单核cpu的情况下,各个进程可以通过一定规则在cpu上并发运行。 二.PCB块 1.PC…

Arduino Uno KY-037声音传感器实验

KY-037声音传感器实验 KY-037声音传感器实验1、 实验内容2、KY-037声音传感器介绍3、实验注意事项4、代码和实验现象 KY-037声音传感器实验 1、 实验内容 通过对KY-037声音传感器吹气&#xff0c;控制LED的打开和关闭&#xff0c;吹一下LED打开&#xff0c;在吹一下LED关闭。…

基于音频Transformer与动作单元的多模态情绪识别算法设计与实现(在RAVDESS数据集上的应用)

摘要&#xff1a;情感识别技术在医学、自动驾驶等多个领域的广泛应用&#xff0c;正吸引着研究界的持续关注。本研究提出了一种融合语音情感识别&#xff08;SER&#xff09;与面部情感识别&#xff08;FER&#xff09;的自动情绪识别系统。在SER方面&#xff0c;我们采用两种迁…

什么是VR实景?有哪些高价值场景?

在数字化浪潮的推动下&#xff0c;虚拟现实技术正以前所未有的速度改变着我们的生活方式和工作模式。 其中&#xff0c;VR实景作为VR技术的一个重要应用场景&#xff0c;独特的沉浸感和交互性&#xff0c;在众多领域展现出应用潜力和高价值场景。什么是VR实景&#xff1f;VR实…

同一无线网络下的设备IP地址是否相同?

在家庭和办公网络普及的今天&#xff0c;许多人都会好奇&#xff1a;连接同一个Wi-Fi的设备是否共享相同的IP地址&#xff1f;这个问题看似简单&#xff0c;实则涉及多个角度。本文将为您揭示其中的技术奥秘。 用一个无线网IP地址一样吗&#xff1f;同一无线网络&#xff08;如…