Java编译时类型与运行时类型

 更新时间:2022年03月03日 16:12:31   作者:LeBron Le  
这篇文章主要介绍了Java编译时类型与运行时类型,文章以父类BaseClass和子类SubClass为例展开对主题的探讨,具有一的 参考价值,需要的小伙伴可以参考一下

1. 定义

多态性是指相同类型的变量在调用同一个方法时,呈现出多种不同的行为特征。

2. 实例说明

在SubClass.java文件中存在两个类:一个是父类BaseClass,另一个是子类SubClass(继承自BaseClass类)。

class BaseClass{
    public int book = 6;
    public void base(){
        System.out.println("父类的普通方法");
    }
    public void test(){
        System.out.println("父类的被覆盖的方法");
    }
}

public class SubClass extends BaseClass {
    public String book = "轻量级Java EE企业应用实战";
    public void test(){
        System.out.println("子类的覆盖父类的方法");
    }
    public void sub(){
        System.out.println("子类的普通方法");
    }
    public static void main(String[] args) {
        // 将子类对象直接赋值给一个父类引用变量ploymophicBc
        BaseClass ploymophicBc = new SubClass();
        System.out.println(ploymophicBc.book);
        ploymophicBc.base();
        ploymophicBc.test();
//        ploymophicBc.sub();
    }
}
父类 BaseClass子类 SubClass
book: intbook: String
void base( )void test()
void test()void sub( )
  • ⭐在子类的main( )方法中,BaseClass ploymophicBc = new SubClass();这行代码将一个子类对象直接赋给一个父类引用变量,无需任何类型转换(或称为向上转型,upcasting),这种向上转型由系统自动完成。
  • BaseClass ploymophicBc = new SubClass();这行代码中的这个引用变量ploymophicBc的编译时类型是BaseClass,而运行时类型是SubClass。当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而非父类方法的行为特征。
ploymophicBc的编译时类型ploymophicBc的运行时类型
BaseClassSubClass
  • System.out.println(ploymophicBc.book);这行代码访问的是父类对象的实例变量,即输出的是“6”。对象的实例变量不具备多态性,所以在程序中输出的是父类BaseClass类的实例变量的值6。
  • ⭐ploymophicBc.base();这行代码中引用变量ploymophicBc调用base( )方法将执行的是从父类继承得到的base( )方法,即输出的是“父类的普通方法”。
  • ⭐⭐⭐ploymophicBc.test();这行代码中当引用变量ploymophicBc调用test( )方法时(父类BaseClass中定义了该方法,而子类SubClass中则覆盖了父类的该方法),实际执行的是当前类的test( )方法,即子类SubClass类中覆盖后的test( )方法,即输出的是“子类的覆盖父类的方法”。
  • ⭐⭐⭐ploymophicBc.sub();这行代码会在编译时引发错误:Cannot resolve method 'sub' in 'BaseClass'。虽然引用变量ploymophicBc实际上确实包含了sub( )方法,但是因为它的编译时类型为BaseClass,因此在编译时无法调用sub( )方法。

3. 注意点

  • 引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法。
  • 个人理解:以ploymophicBc.test();这行代码为例,引用变量ploymophicBc在编译阶段只能调用其编译时类型(即父类BaseClass类)所具有的方法(即BaseClass类的test( )方法),但是在运行时它实际执行的是运行时类型(即子类SubClass类)所具有的方法(即SubClass类的test( )方法)。
  • 编写Java代码时,引用变量只能调用声明该变量时所用类里包含的方法。例如,通过Object p = new Person(); 这行代码定义了一个变量p,则这个变量p只能调用Object类的方法,而不能调用Person类里定义的方法。
  • 通过引用变量来访问其包含的实例变量时,系统总是试图访问它编译时类型所定义的成员变量,而不是它运行时类型所定义的成员变量。
  • ploymophicBc.base();、ploymophicBc.test();这两行代码能够运行、而ploymophicBc.sub();这行代码不能运行的根本原因就在于:
    • ①引用变量ploymophicBc在调用base( )方法的时候,由于它在编译时类型为BaseClass,并且BaseClass类中包含base( )方法,所以可以通过编译。在运行时由于SubClass类中不具有base( )方法,所以该引用变量在调用base( )方法的时候只能调用从父类BaseClass类继承而来的base( )方法。
    • ②引用变量ploymophicBc在调用test( )方法的时候,由于它在编译时类型为BaseClass,而BaseClass类中含有test( )方法,所以该行代码可以通过编译。个人理解就是借由编译时类型通过了编译,然后后头就根据“运行时则执行它运行时类型所具有的方法”这个原则,由于它运行时类型为SubClass,所以最终实际执行的时SubClass类所具有的test( )方法。
    • ③引用变量ploymophicBc在调用sub( )方法的时候,由于它在编译时类型为BaseClass,然而BaseClass类并没有sub( )方法,所以它连编译这一关都过不了,会报错。

 到此这篇关于Java编译时类型与运行时类型的文章就介绍到这了,更多相关Java编译时类型与运行时类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 还在用if(obj!=null)做非空判断,带你快速上手Optional

    还在用if(obj!=null)做非空判断,带你快速上手Optional

    这篇文章主要介绍了还在用if(obj!=null)做非空判断,带你快速上手Optional,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • centos下安装openjdk21的详细图文教程

    centos下安装openjdk21的详细图文教程

    这篇文章主要介绍了centos下安装openjdk21的相关资料,文章详细介绍了如何手动下载、解压和配置OpenJDK 21,包括下载OpenJDK、上传到指定目录、解压、编辑环境变量和验证安装成功的过程,需要的朋友可以参考下
    2024-12-12
  • 详解Maven打包和运行

    详解Maven打包和运行

    这篇文章主要介绍了Maven打包和运行的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • resty client使用Java客户端来访问Api

    resty client使用Java客户端来访问Api

    这篇文章主要介绍了resty-client使用Java客户端来访问Api的验证权限,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • Security框架:如何使用CorsFilter解决前端跨域请求问题

    Security框架:如何使用CorsFilter解决前端跨域请求问题

    这篇文章主要介绍了Security框架:如何使用CorsFilter解决前端跨域请求问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • SpringBatch从入门到精通之StepScope作用域和用法详解

    SpringBatch从入门到精通之StepScope作用域和用法详解

    这篇文章主要介绍了SpringBatch从入门到精通之StepScope作用域和用法详解,主要包括IOC容器中几种bean的作用范围以及可能遇到的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Java Math类的三个方法ceil,floor,round用法

    Java Math类的三个方法ceil,floor,round用法

    这篇文章主要介绍了Java Math类的三个方法ceil,floor,round用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Spring中的refresh方法分析

    Spring中的refresh方法分析

    这篇文章主要介绍了Spring中的refresh方法分析,文章围绕主题展开详细的refresh方法相关资料介绍,需要的小伙伴可以参考一下
    2022-05-05
  • Spring缓存注解@Cacheable @CacheEvit @CachePut使用介绍

    Spring缓存注解@Cacheable @CacheEvit @CachePut使用介绍

    Spring在3.1版本,就提供了一条基于注解的缓存策略,实际使用起来还是很丝滑的,本文将针对几个常用的注解进行简单的介绍说明,有需要的小伙伴可以尝试一下
    2021-07-07
  • Java经典面试题汇总:Spring

    Java经典面试题汇总:Spring

    本篇总结的是Spring框架相关的面试题,后续会持续更新,希望我的分享可以帮助到正在备战面试的实习生或者已经工作的同行,如果发现错误还望大家多多包涵,不吝赐教,谢谢
    2021-07-07

最新评论