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

网友投稿 217 2022-10-25

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

目录1.定义2.实例说明3.注意点

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子类 SubClassbook: intbook: Stringvoid 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( )方法,所以它连编译这一关都过不了,会报错。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:dubbo-go v3 版本 go module 踩坑记
下一篇:跟我学docker:Docker-Compose介绍与安装配置
相关文章

 发表评论

暂时没有评论,来抢沙发吧~