Java super、this、static关键字实践案例

 更新时间:2025年11月03日 09:42:04   作者:美味蛋炒饭.  
本文详细介绍了Java继承的概念,包括继承的本质、创建子类对象的过程、方法重写和方法重载的区别,以及Java的继承层次,此外,还讨论了super和this关键字的用法,以及static关键字的归属、内存模型、静态方法的调用限制和静态代码块的执行时机,感兴趣的朋友一起看看吧

一.Java继承

(1)继承

继承的本质就是代码的复用,子类继承父类的全局变量和方法(public,protected)

public class Animal{
    public String name;
    public String color;
    public void run(){
    }
    public void eat(){
    }
    //....
}
public class Dog extends Animal{
    public String name;
    public String color;
    public void run(){
    }
    public void eat(){
    }
    //....
}
public class Cat extends Animal{
    public String name;
    public String color;
    public void run(){
    }
    public void eat(){
    }
    //....
}
  • 父类 Animal:定义了公共的成员变量namecolor,以及公共方法run()eat(),这些是动物类的通用属性和行为。
  • 子类 Dog 和 Cat:通过extends关键字继承Animal类,从而拥有了父类的namecolorrun()eat()。

(2)继承父类并创建对象在内存当做发生什么

创建子类的时候一定会去创建父类对象---->先创建父类对象,在创建子类对象

  • 当创建子类对象(如CatDog)时,会先创建父类Animal的对象(堆中0x1标识的区域,包含父类的namecolorrun()eat()),再基于父类对象创建子类对象(如cat 0x2对应的堆区域,继承父类的结构后,还会添加子类自身的特性)。

  • 父类 Animal:包含构造方法 public Animal(){ System.out.println("我是Animal"); },当父类对象被创建时,该构造方法会执行,打印 “我是 Animal”。
  • 子类 Cat:继承自 Animal,其构造方法 public Cat(){ System.out.println("我是Cat"); } 会在父类构造方法执行后执行,打印 “我是 Cat”。
  • 测试类 Test:在 main 方法中创建 Cat 对象 Cat cat = new Cat();,触发构造方法的执行链。

(3)Java程序为什么new 子类对象时,结果先创建父类对象在创建子类对象

原因在于有方法重写

*****方法重写和方法重载的区分

1)方法重写:父类的方法被子类重写(父类当中的方法不应完全适用于子类)

  • 左侧 “cat 0x1” 代表子类 Cat 的对象(0x1 是对象在内存中的标识)。
  • 上方区域包含run()eat()方法和name=nullcolor=null属性,代表父类的成员(方法和属性)
  • 下方区域的run()方法(浅蓝色)代表子类 Cat 对父类 run () 方法的重写—— 子类通过重写,让run()方法的行为更贴合 “猫” 的特性,而父类的eat()方法等未被重写时,子类会继承使用

2)方法重载:发生在同一个类当中,方法名称相同,参数列表不同的方法,叫做方法

Java程序是通过方法的签名来验证这是不是一个方法(方法签名:方法名+参数列表(数据类型)

public class Cat extends Animal {
    public void run() {
        System.out.println("迈开四只脚跑……");
    }
    public void jump(){
        System.out.println("跳起来了……");
    }
    public void jump(int a){
        System.out.println("跳起来了……");
    }
    public void jump(String name){
    }
}

Cat类中,jump方法出现了多次:

  • public void jump(){...}(无参数)
  • public void jump(int a){...}(参数为int类型)
  • public void jump(String name){...}(参数为String类型)这几个方法名称相同,但参数列表不同,属于方法重载的典型案例;而run方法只有一个定义,不涉及重载。

(4)Java继承层次--------->Java只支持单继承

一个子类只能有一个父类,一个父类可以有多个父类

是用来防止因多继承带来的复杂逻辑和内存管理问题

  • Animal是顶层父类,CatDog都直接继承自Animal(体现 “一个父类可以有多个子类”)。
  • Dog作为父类,又有小黑狗类小黄狗类小白狗类三个子类。
  • 图中 “不允许” 的箭头表示:小黑狗类不能同时继承CatDog,因为 Java 不支持多继承(一个子类只能有一个直接父类)。

二.super关键字

super代表父类,调用父类当中的方法和变量

public void jump(int a) {
    super.color = "黑色";
    super.run();
    super.eat();
    System.out.println("猫跳高了......");
}

jump(int a)方法中:

  • super.color = "黑色";:调用并设置父类的成员变量color的值为 “黑色”。
  • super.run();super.eat();:调用父类的run()方法和eat()方法。
  • 最后执行子类自身的逻辑System.out.println("猫跳高了……");

三.this关键字------------>this代表当前对象

(1)this属性名称

Java中为解决变量的名称冲突和不确定性问题,引入关键字this代表其所在方法的当前对象的引用。

(2)this:方法名

代表当前的对象调用某一方法。

(3)注意

1)不能在普通方法当前中只能在构造方法中使用。

2)在构造方法当中必须是第一条语句。

3)不能和super()一起使用。

四.static关键字

(1)static的 “归属” 本质

static 修饰的元素属于 “类”,而非类的 “对象(实例)”。

示例:.java 源文件(如 Hello.java)编译为 .class 字节码后,static 成员随类加载到方法区,不依赖对象存在。

(2)static的内存模型(JVM 视角)

JVM 内存分为虚拟机栈、堆、方法区static 成员的存储规则如下:

  • 静态变量 / 方法 / 代码块:存储在方法区的 “类信息” 区域,属于类的共享资源。
  • 非静态方法:也存储在方法区,但属于 “对象可调用” 的成员(需通过对象触发)。
  • 堆内存:仅存储对象的实例数据,static 成员不在这里。
  • 虚拟机栈:存储方法调用的栈帧,执行 mainrun 等方法时的局部变量在此分配。
public class TestConfigParser {
    public static void main(String[] args) {
        eat();
        new TestConfigParser().run();
    }
    public void run(){}
    public static void eat(){}
}

(3) 静态方法(类方法)

  • 访问方式
    • 推荐:类名.方法名()(如 TestConfigParser.eat());
    • 不推荐:对象.方法名()(易混淆,不体现 “类归属” 本质)。
  • 调用限制
    • 静态方法中不能直接调用非静态方法(非静态方法属于 “对象”,静态方法加载时可能还没有对象);
    • 非静态方法中可以调用静态方法(对象存在时,类一定已加载);
    • 静态方法中不能使用 this 关键字this 代表 “当前对象”,静态方法不依赖对象)。
public class TestConfigParser {
    public static void main(String[] args) {
        new TestConfigParser().run(); // 非静态方法需通过对象调用
    }
    public void run(){} // 非静态方法
    public static void eat(){} // 静态方法
}

(4)静态代码块

  • 执行时机:在 main 方法之前执行,且仅执行一次(类加载时执行)。
  • 作用:用于初始化静态变量、加载资源(如配置文件、数据库驱动)等 “类级别的初始化操作”。
public static void main(String[] args) {
    Demo demo = new Demo();
    Demo demo1 = new Demo();
    Demo demo2 = new Demo();
    demo.from = "中国"; // 修改静态变量
    System.out.println(demo.from);   // 输出“中国”
    System.out.println(demo1.from);  // 输出“中国”
    System.out.println(demo2.from);  // 输出“中国”
}

(5)static的加载顺序

  • 规则:static修饰的代码块 在main方法之前执行,先加载父类,在加载子类,创建子类对象之前先创建父类对象
  • 示例代码(体现父子类静态加载顺序):
public class Test extends Base {
    static {
        System.out.println("Test static");
    }
    public Test() {
        System.out.println("Test constructor");
    }
    public static void main(String[] args) {
        new Test();
    }
}
class Base {
    static {
        System.out.println("Base static");
    }
    public Base() {
        System.out.println("Base constructor");
    }
}
// 执行结果:
// Base static
// Test static
// Base constructor
// Test constructor
class Demo {
    public Demo(String aa) {
        System.out.println("=====" + aa);
    }
    static {
        System.out.println("11");
    }
    public static Demo demo = new Demo("+++");
    static {
        System.out.println("22");
    }
}
class Test {
    public static void main(String[] args) {
        Demo demo = new Demo("----");
    }
}
//11
//=====+++
//22
//=====----

到此这篇关于Java super、this、static关键字的文章就介绍到这了,更多相关java super this static关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java NIO 通道概念选择器使用示例详解

    Java NIO 通道概念选择器使用示例详解

    这篇文章主要为大家介绍了Java NIO 通道概念选择器使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Java IO流操作(PipeInputStream、SequenceInputStream、BufferedInputStream)

    Java IO流操作(PipeInputStream、SequenceInputStream、Buffered

    管道流主要用于线程间通信,分为管道输入流(PipeInputStream)和管道输出流(PipeOutputStream),本文介绍了如何通过管道流进行数据发送和接收,具有一定的参考价值,感兴趣的可以了解一下
    2024-10-10
  • Elasticsearch 映射参数详解 fields

    Elasticsearch 映射参数详解 fields

    这篇文章主要介绍了fields Elasticsearch 映射参数fields,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java 将PPT幻灯片转为HTML文件的实现思路

    Java 将PPT幻灯片转为HTML文件的实现思路

    本文以Java程序代码为例展示如何通过格式转换的方式将PPT幻灯片文档转为HTML文件,本文通过实例代码图文相结合给大家分享实现思路,需要的朋友参考下吧
    2021-06-06
  • Java中实现OCR识别读取图片中的文字

    Java中实现OCR识别读取图片中的文字

    图片内容一般无法编辑,如果想要读取图片中的文本,我们需要用到OCR工具,本文将介绍如何在Java中实现OCR识别读取图片中的文字,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • spring中@Reference注入为空的解决方法

    spring中@Reference注入为空的解决方法

    今天上线遇到了问题,所以抽空记录一下,本文主要介绍了spring中@Reference注入为空的解决方法,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06
  • itext生成PDF设置页眉页脚的实例详解

    itext生成PDF设置页眉页脚的实例详解

    这篇文章主要介绍了itext生成PDF设置页眉页脚的实例详解的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09
  • 深入了解SpringBoot中@InitBinder注解的使用

    深入了解SpringBoot中@InitBinder注解的使用

    这篇文章主要介绍了深入了解SpringBoot中@InitBinder注解的使用,@InitBinder注解可以作用在被@Controller注解的类的方法上,表示为当前控制器注册一个属性编辑器,用于对WebDataBinder进行初始化,且只对当前的Controller有效,需要的朋友可以参考下
    2023-10-10
  • mybatis中mapper代理的生成过程全面分析

    mybatis中mapper代理的生成过程全面分析

    这篇文章主要为大家介绍了mybatis中mapper代理的生成过程全面分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • springBoot2.X配置全局捕获异常的操作

    springBoot2.X配置全局捕获异常的操作

    这篇文章主要介绍了springBoot2.X配置全局捕获异常的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07

最新评论