为什么要区分编译时类型和运行时类型?

看这样一句代码:Person p=new Women()(Women类继承自Person类)那么,假如p的属性修饰符为public 访问属性时得到的是Person类的属性还是Women类的属性,方法调用又是哪个类?答案:会得到Person类的属性,调用Women类的方法。为什么会这样呢?这里就需要知道什么是编译时类型和运行时类型,Java程序状态会分为编译和运行这两种状态,编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用,回到刚刚那句代码,显然,p这个引用就是在编译时创建的,那么,p的编译时类型就是Person了,当运行这句java代码时,JVM在堆中为p新建一块内存,对应new Women()这句代码,所以p的运行时类型就是Women。有这样一条规则,对象调用编译时类型的属性和运行时类型的方法。下面先用代码表示这样的结果,然后再说明我个人的一些理解。

code1

public class TestDemo1 {

public static void main(String[] args) {

// TODO Auto-generated method stub

Person p=new Women();

System.out.println("p.name:"+p.name);

p.show();

}

}

class Person{

public String name;

public Person()

{

name="person";

}

public void show()

{

System.out.println("class person's show()");

}

}

class Women extends Person

{

public String name;

public Women()

{

name="women";

}

public void show()

{

System.out.println("class women's show()");

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

结果如下

从代码运行结果可以看出,p调用的属性属于Person类,而调用的方法是Women类的,验证了上面的规则–对象调用编译时类型的属性和运行时类型的方法

个人理解

这里属于我个人的理解,可能有错,以后发现会重新修正

根据上述规则

根据继承的特点我们可以知道,子类会继承父类非私有的属性和方法,也就是说,父类的(非私有)属性也会出现在子类中,当然,这是显而易见的,然而关键在于,如果子类重新定义了这一属性,会怎么样呢?实际上,父类的属性并不会被覆盖,为了方便起见,我把从父类继承来的属性记为–

属性 而自己重新定义的同名属性为–属性 这样,在子类中,会有两个属性 即:属性

属性,那么如何调用呢?–解答:<>中的内容对应着调用该属性的对象的编译时类型,编译时类型为父类,调用属性

,另一种情况就是调用子类的属性了。下面用图来表示:

Class

A中定义属性a,Class B继承自A,重新定义了属性a,此时,B中有编译时类型为A的属性a和编译时类型为B的属性a,Class

C继承自B,自己重新定义了属性a,这时,C具有三种编译时类型的属性a。这样就好看多了,不知道应该调用的属性是哪个类的,就只要分析自己的编译时类型就可以了,调用方法其实不用在意,直接调用运行时类型的方法即可(运行时类型还是比较容易看的)。

就上图的例子我们用代码测试如下

code2

public class TestDemo2 {

public static void main(String[] args) {

// 编译时类型为A,输出应该是A

System.out.println("编译时类型为A,输出应该是A");

A a=new A();

System.out.println(a.name);

A ab=new B();

System.out.println(ab.name);

A ac=new C();

System.out.println(ac.name);

// 编译时类型为B,输出应该是B

System.out.println("编译时类型为B,输出应该是B");

B b=new B();

System.out.println(b.name);

B bc=new B();

System.out.println(bc.name);

// 编译时类型为C,输出应该是C

System.out.println("编译时类型为C,输出应该是C");

C c=new C();

System.out.println(c.name);

}

}

class A

{

String name="A";

}

class B extends A

{

String name="B";

}

class C extends B

{

String name="C";

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

运行结果如下

根据运行结果上述解释应该是合理的!

java 运行 对象_java实例对象的编译时类型和运行时类型相关推荐

  1. 浅谈Java异常及其编译时异常和运行时异常的区别

    异常是程序编码和运行时经常发生的事件,了解异常有助于我们提高代码质量,增强系统的健壮性,这里总结一下Java编程中的异常.以及Java编译时异常和运行时异常的区别,并列举几种常见的异常,以供参考学习. ...

  2. java中的编译时异常和运行时异常

    首先区分一下 编译时异常和运行时异常 运行时异常,也就是extends RuntimeException的异常编译时不用try{}catch(){}和throws 编译时异常,也就是extends E ...

  3. 异常---编译时异常和运行时异常:IO异常、NullPointerException、ArrayIndexOutBoundsException、ClassCastExoeption

    一.概述 1.定义: 程序运行过程中的发生了不正常的情况 2.异常处理机制和作用----JVM虚拟机打印的 java语言时很完善的语言,提供了异常处理方式,出现异常,将异常信息打印到输出控制台,供程序 ...

  4. 编译时类型和运行时类型到底是什么?

    最近在看多态,里面有一句话困扰了我很久,就是 编译时类型和运行时类型 ps:多态定义:把子类对象直接赋给父类的引用时,当运行时调用该引用类型的方法时,其方法行为总是表现出子类的行为特征,而不是父类的行 ...

  5. 编译时异常和运行时异常区别

    文章目录 1.编译时异常因为什么而得名 2.编译时异常和运行时异常区别 3.编译时异常还有其他名字 4.运行时异常还有其他名字 5.所有异常都发生在运行阶段的 1.编译时异常因为什么而得名 编译时异常 ...

  6. C++编译时多态和运行时多态

    C++编译时多态和运行时多态 作者:melonstreet 出处:https://www.cnblogs.com/QG-whz/p/5132745.html 本文版权归作者和博客园共有,欢迎转载,但未 ...

  7. 编译时异常和运行时异常的区别

    编译时异常和运行时异常的区别 参考文章: (1)编译时异常和运行时异常的区别 (2)https://www.cnblogs.com/lxl57610/p/6716252.html (3)https:/ ...

  8. java编译时多态和运行时多态_运行时多态、编译时多态和重载、重写的关系(不区分Java和C#,保证能看懂!)...

    以前在大学学习OOP的时候,知道了重载和重写的区别,但如果要把他们和多态联系起来,我想很多新手朋友和我当初一样是死记的,可是时间长了,自然而然就忘记了,最近在写测试的时候,终于"开窍&quo ...

  9. java 语法错误_java菜鸟提问:编译时异常和语法错误的区别?

    语法错误是你真写错了,比如"All the people here work hardly."这句话就是语法错误,hard也可用作副词,所以"All the people ...

最新文章

  1. 应届毕业生没有工作经验,怎么才能找到合适的工作?
  2. redis详解(四)-- 高可用分布式集群
  3. [zz]c++ list sort方法
  4. 所以Apache基金会不受美国法律约束?
  5. CentOS 7 yum 安装php5.6
  6. C#单元测试如何查看输出的调试信息?
  7. 安卓学习笔记20:Fragment入门
  8. 安兔兔2月Android手机性价比榜出炉:Redmi包揽前三
  9. android 钢琴识别音阶对错_钢琴为什么会成为“乐器之王”
  10. 【书籍推荐】《美国黒室》
  11. BGSOUND与EMBED的区别
  12. Oracle GoldenGate 之 Director 监控工具安装和邮箱报警
  13. Xshell注册激活教程
  14. xshell查看hdfs文件目录路径_hdfs的shell操作
  15. 齐齐哈尔市全国计算机等级考试,2021年9月黑龙江省齐齐哈尔市全国计算机等级考试报名时间...
  16. Python 调用 ImageMagick 将常规图片转成 .ico 图片
  17. Broadcast Receiver(一)
  18. html5如何快速选择工具,PS抠图教程!教你PHOTOSHOP中5个快速选择工具
  19. 手写数字的分割和识别
  20. 杨米尔斯理论讲了什么

热门文章

  1. 微信重磅功能更新!加好友按人数收费,视频号付费订阅、微信版“知乎”来了...
  2. 将来有机会把自己的院子建成这种
  3. 计算机左侧没有桌面菜单栏,AI软件左侧的工具栏不见了没有了怎么显示出来
  4. 硬盘、光驱、刻录机维修技术
  5. 如何提高电商广告投放的转化率?
  6. Numpy 数组切片
  7. 筑龙网下载的文件格式是php_建筑工程竣工验收资料填报指南(范本)
  8. ios html调起高德地图,iOS 调用百度地图, 高德地图,苹果自带的地图
  9. Spark SQL操作多数据源
  10. 如何在Ubuntu上方便使用OpenAI API key