别再死记硬背!Java继承的“血缘密码”与避坑指南(最新整理)

 更新时间:2026年08月01日 09:17:00   作者:第六章初  
在Java中,继承是一种非常重要的面向对象编程概念,它允许我们通过重用已有的代码来创建新的类,然而,不恰当的继承使用可能会导致一些问题,比如“血缘密码”(Inheritance Pitfalls)和设计上的缺陷,下面我将解释一些常见的继承问题,并给出一些避坑指南

前言

  • java是面向对象的,其中继承是很重要的属性,我们之前学习过类和对象
    和包的知识,在这样的基础上再回看学习继承就不会很困难了,让我们开始吧~~
  • 还有就是我们在以后的学习中一定要引入类的知识,不要给自己设置困难,相信自己,可以挺过来的~
  • 我们以学生资料为背景,保持专注,直接发车~~

一 继承

什么是继承

  • 在一个大学中,既有本科生也有研究生,但是他们或多或少有一些共性,这些共性我们一般就不会单独的进行书写,而是写一个类,这个类可以被本科生和研究生进行调取,这是实际上就是继承。
  • 核心就是::共性的抽取,实现代码复用。
  • 继承(inheritance)机制:是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许程序员在保持
    原有类特性的基础上进⾏扩展,增加新功能,这样产⽣新的类,称派⽣类。继承呈现了⾯向对象程序
    设计的层次结构,体现了由简单到复杂的认知过程。

基本代码示例

  • 我们通过三个类型和一个测试类进行实例学习
// 这是一个父类,用来表示学生信息
public class Student {
    public String name;
    public int age;
    public String id;
    public String major;
    public void print(){
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("ID: " + id);
        System.out.println("Major: " + major);
    }
}
// 子类:本科生 继承自学生类
public class Undergraduate extends Student {
        void undergraduate(){
            System.out.println(name+"正在学习基础课程");
        }
}
//子类:研究生,继承自学生类
public class Postgraduate  extends Student {
    void postgraduate(){
        System.out.println(name+"正在做实验");
    }
}

测试类

public class test20250807 {
    public static void main(String[] args) {
        Undergraduate u = new Undergraduate();
        Postgraduate p = new Postgraduate();
        u.name = "张三";
        p.name = "李四";
        u.undergraduate();
        p.postgraduate();
    }
}

继承语法

在java中我们通过extend关键字进行继承

子类中访问父类的成员变量/成员方法

  • 我们已经是创建了相应的子类和父类,那么怎么在子类中引用父类的成员变量和成员方法。
不存在同名的成员变量时

在子类中正常访问

public class Base {
    int a;
    int b;
  }
public class Derived extends Base{
     int c;
    public void method(){
    a = 10; // 访问从⽗类中继承下来的a
    b = 20; // 访问从⽗类中继承下来的b
    c = 30; // 访问⼦类⾃⼰的c
   }
}
存在同名的成员变量/方法时
  • 优先访问子集的成员变量或成员方法。
    public static void main(String[] args) {
        Undergraduate u = new Undergraduate();
        Postgraduate p = new Postgraduate();
        u.print();
        p.print();
//子类
public class Undergraduate extends Student {
    public void print() {
        System.out.println("子类中的print");
    }
 }
//父类
public class Student {
    public String name;
    public int age;
    public String id;
    public String major;
    public void print(){
        System.out.println("父类中的print");
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("ID: " + id);
        System.out.println("Major: " + major);
    }
}

结果:

  • 如果在子类中访问父类同名的成员方法,需要引入super关键字。
子类的构造方法
  • 在java中,当我们构造子类对象时,要先调用父类的构造方法,然后执行子类的构造方法。我们需要在子类对象构造之前,先帮助父类对其中的成员进行初始化。
  • 需要注意的是super()只能在子类的构造方法中的第一行。
  • 当父类是不带参数的构造方法而且只有一个时,在子类的构造方法中会有一个默认的super()。
  • Super只能在子类的构造方法中出现一次,不能和this同时出现。(原因就是都是在第一行)

代码示例:

public class Base {
    public Base(int a){
        System.out.println("Base class constructor");
    }
public class Derived extends Base {
    Derived() {
        super(10);  //这里对父类进行初始化
        System.out.println("Derived Constructor Called!");
    }
 }
public class test202508081 {
    public static void main(String[] args) {
        Derived d = new Derived();
    }
}

结果:

二 this和super

相同点

  • 都是Java中的关键字
  • 只能在类的⾮静态⽅法中使⽤,⽤来访问⾮静态成员⽅法和字段
  • 在构造⽅法中调⽤时,必须是构造⽅法中的第⼀条语句,并且不能同时存在。

不同点

  • this是当前对象的引用,当前对象即调⽤实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用。
  • 在非静态成员方法中,this用来访问本类的方法和属性,super⽤来访问⽗类继承下来的⽅法和属性
  • 在构造方法:this(…)⽤于调⽤本类构造⽅法,super(…)⽤于调⽤⽗类构造方法,两种调用不能同时在构造⽅法中出现
  • 构造方法中⼀定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

三 继承关系上代码块等的初始化顺序

在此之前我们复习看一之前的代码块的初始化顺序:

  • 静态代码块
  • 实例代码块
  • 构造代码块

加入继承:

package student;// 这是一个父类,用来表示学生信息
public class Student {
    public String name;
    public int age;
    static{
        System.out.println("student静态代码块");
    }
    {
        System.out.println("student(示例代码块)非静态代码块");
    }
    public Student(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("student带两个参数的构造代码块");
    }
public class Undergraduate extends Student {
    static{
        System.out.println("Undergra静态代码块");
    }
    {
        System.out.println("Undergra(示例代码块)非静态代码块");
    }
    public Undergraduate(String name, int age) {
        super(name,age);
        System.out.println("Undergra带两个参数的构造代码块");
    }
public class test20250807 {
    public static void main(String[] args) {
        Undergraduate u = new Undergraduate("张三",20);

结果:

  • 小结一下
  • ⽗类静态代码块优先于⼦类静态代码块执⾏,且是最早执⾏
  • ⽗类实例代码块和⽗类构造⽅法紧接着执⾏
  • ⼦类的实例代码块和⼦类构造⽅法紧接着再执⾏
  • 第⼆次实例化⼦类对象时,⽗类和⼦类的静态代码块都将不会再执⾏(结果展示)

四 访问修饰限定符-protected 关键字

不能通过父类类名进行访问

如果被 protected 关键字修饰该类当中成员变量,成员⽅法等表⽰要么只能在同⼀个包中的类中进⾏访问,要么在不同包中只能通过在继承关系上的⼦类对象来访问。

五 继承分类

多继承是不存在的,不能同时有多个父类。

六 final关键字

  • 被修饰的就不可以在被再次继承
    1.可以修饰成员变量
    2.可以修饰类

七 继承和组合

  • 有和是的关系
//组合
// 轮胎类
class Tire{
// ...
}
// 发动机类
class Engine{
// ...
}
// ⻋载系统类
class VehicleSystem{
// ...
}
class Car{
private Tire tire; // 可以复⽤轮胎中的属性和⽅法
private Engine engine; // 可以复⽤发动机中的属性和⽅法
private VehicleSystem vs; // 可以复⽤⻋载系统中的属性和⽅法
// ...
}
//继承
// 奔驰是汽⻋
class Benz extend Car{
// 将汽⻋中包含的:轮胎、发送机、⻋载系统全部继承下来
}

总结

到此这篇关于别再死记硬背!Java继承的“血缘密码”与避坑指南的文章就介绍到这了,更多相关java继承避坑指南内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot整合Log4j2.xml的问题及解决方法

    Spring Boot整合Log4j2.xml的问题及解决方法

    这篇文章主要介绍了Spring Boot整合Log4j2.xml的问题,本文给大家分享解决方案,需要的朋友可以参考下
    2023-09-09
  • 如何在Java中判断两个Long类型是否相等

    如何在Java中判断两个Long类型是否相等

    这篇文章主要介绍了如何在Java中判断两个Long类型是否相等,文章围绕主题展开详细的内容介绍,具有一定的 参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • SpringBoot+Thymeleaf+ECharts实现大数据可视化(基础篇)

    SpringBoot+Thymeleaf+ECharts实现大数据可视化(基础篇)

    本文主要介绍了SpringBoot+Thymeleaf+ECharts实现大数据可视化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-06-06
  • MyBatis-Plus如何最优雅最简洁地完成数据库操作

    MyBatis-Plus如何最优雅最简洁地完成数据库操作

    Mybatis-Plus是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生,下面这篇文章主要给大家介绍了关于MyBatis-Plus如何最优雅最简洁地完成数据库操作的相关资料,需要的朋友可以参考下
    2022-03-03
  • 全面解读Java编程中的内部类

    全面解读Java编程中的内部类

    这篇文章主要介绍了Java的内部类,包括类成员访问等Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • SpringCloud的全链路灰度发布方案详解

    SpringCloud的全链路灰度发布方案详解

    这篇文章主要介绍了SpringCloud的全链路灰度发布方案详解,灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式,灰度发布可以保证系统的稳定性, 在初始灰度的时候可以发现, 调整问题, 保证其影响度,需要的朋友可以参考下
    2023-09-09
  • 详解Spring Batch 轻量级批处理框架实践

    详解Spring Batch 轻量级批处理框架实践

    这篇文章主要介绍了详解Spring Batch 轻量级批处理框架实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06
  • 解读easyexcel中的常用注解

    解读easyexcel中的常用注解

    这篇文章主要介绍了关于easyexcel中的常用注解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • java中CopyOnWriteArrayList源码解析

    java中CopyOnWriteArrayList源码解析

    为了将读取的性能发挥到极致,jdk中提供了CopyOnWriteArrayList类,下面这篇文章主要给大家介绍了关于java中CopyOnWriteArrayList源码解析的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • Java 中的 String对象为什么是不可变的

    Java 中的 String对象为什么是不可变的

    String对象是不可变的,但这仅意味着你无法通过调用它的公有方法来改变它的值。本文给大家介绍java中的string对象为什么是不可变的,需要的朋友一起了解了解吧
    2015-10-10

最新评论