A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张凯 中级黑马   /  2012-7-23 07:24  /  1519 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

先看下代码:

  1. ParentClass:
  2. package com.design;
  3. class ParentClass {
  4. public static String staticField = "父类静态变量";
  5. public final String finalField = "父类常量";
  6. public static final String staticFinalField = "父类静态常量";
  7. public static void getStr(){
  8. System.out.println("child output");
  9. }
  10. }

  11. SubClass:
  12. package com.design;
  13. public class SubClass extends ParentClass {
  14. public static String staticField = "子类静态变量";
  15. public final String finalField = "子类常量";
  16. public static final String staticFinalField = "子类静态常量";
  17. public static void getStr(){
  18. System.out.println("child output");
  19. }

  20. public static void main(String[] args) {
  21. //这里到底发生了什么?
  22. ParentClass subClass = new SubClass(); //(1)
  23. System.out.println(subClass.staticField);
  24. System.out.println(subClass.finalField);
  25. System.out.println(subClass.staticFinalField);
  26. subClass.getStr();
  27. //为什么与(1)不同呢 SubClass subClass2 = new SubClass();
  28. System.out.println(subClass2.staticField);
  29. System.out.println(subClass2.finalField);
  30. System.out.println(subClass2.staticFinalField);
  31. subClass2.getStr();
  32. }
  33. }
复制代码
运行结果:
父类静态变量
父类常量
父类静态常量
child output
子类静态变量
子类常量
子类静态常量
child output


我想问的是父类子类有相同的变量声明,为什么变量取决于引用而不是实际的对象?

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

3 个回复

正序浏览
  1. public static void main(String[] args) {
  2. //这里到底发生了什么?
  3. ParentClass subClass = new SubClass(); //多态的使用。父类的引用指向了自己的子类对象。相当于对SubClass()做了类型的提升,使它向上转型。所以下面的SubClass在调用方法时,都是调用的父类方法。如果这时想使用子类的方法,应向下转型,SubClass subClass1=(SubClass)subClass;这时subClass1才能调用子类方法。
  4. System.out.println(subClass.staticField);
  5. System.out.println(subClass.finalField);
  6. System.out.println(subClass.staticFinalField);
  7. subClass.getStr();
  8. //为什么与(1)不同呢 SubClass subClass2 = new SubClass(); //这里没有使用多态,没有发生转型。还是子类引用指向子类对象。
  9. System.out.println(subClass2.staticField);
  10. System.out.println(subClass2.finalField);
  11. System.out.println(subClass2.staticFinalField);
  12. subClass2.getStr();
  13. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

回复 使用道具 举报
静态成员是存在于方法区内,实际的对象是在堆内存中,对象的引用是在栈内存中。subClass变量是ParentClass类的引用,指向ParentClass自己的静态成员,同时指向了堆内存中SubClass类的实际对象。subClass2 变量是SubClass类的引用,指向SubClass自己的静态成员,同时指向了堆内存中SubClass类的实际对象。
静态成员可以直接通过类名调用,说明静态成员是与是否创建实际的对象无关的。
回复 使用道具 举报
public static void main(String[] args)
{
//这里到底发生了什么?
ParentClass subClass = new SubClass(); //这句话是父类的引用指向子类对象,是多态的体现形式
System.out.println(subClass.staticField);
System.out.println(subClass.finalField);
System.out.println(subClass.staticFinalField);
subClass.getStr();
//为什么与(1)不同呢
SubClass subClass2 = new SubClass(); //这里是子类的引用指向子类对象
System.out.println(subClass2.staticField);
System.out.println(subClass2.finalField);
System.out.println(subClass2.staticFinalField);
subClass2.getStr();
}


ParentClass subClass = new SubClass();//这句话是父类的引用指向子类对象,是多态的体现形式
在多态中,成员变量的特点:
无论在编译和运行,都参考左边(引用型变量所属的类)。
当父类和子类出现重名变量的时候,多态情况下看的是左边(引用型变量所属的类)。
所以:
System.out.println(subClass.staticField);
System.out.println(subClass.finalField);
System.out.println(subClass.staticFinalField);
执行的结果是:
父类静态变量
父类常量
父类静态常量
System.out.println(subClass2.staticField);
System.out.println(subClass2.finalField);
System.out.println(subClass2.staticFinalField);
执行的结果是:
子类静态变量
子类常量
子类静态常量

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马