之前搞错了,变量没有“重写”一说,只有方法才能被“重写”。如果我们在子类中声明了一个和父类中一样的变量,那么实际的情况是,子类的内存堆中会有类型和名字都相同的两个变量。

  现在考虑一种情况,如下所示,我们在子类中声明一个名字与父类中变量一样,但是类型不同的变量i(一个int,一个double),同时我们在父类中有一个print()打印i,那么当我们从子类的对象中调用这个print()时,他到底会打印哪一个i?

  1. class SuperClass {
  2. public int i;
  3. SuperClass(){
  4. i=10;
  5. System.out.println("SuperClass() is construted.");
  6. }
  7. public void print(){
  8. System.out.println("the i in SuperClass: "+i);
  9. }
  10. }
  11.  
  12. class SubClass extends SuperClass {
  13. public double i;
  14. SubClass(){
  15. i=20.0;
  16. System.out.println("SubClass() is constructed.");
  17. }
  18. public void printSub(){
  19. System.out.println("the i in SubClass: "+i);
  20. }
  21. }
  22.  
  23. public class TestDemo {
  24. public static void main(String[] args) {
  25. SubClass sub=new SubClass();
  26. System.out.println("sub.i is: "+sub.i);
  27. sub.printSub();
  28. sub.print();
  29. }
  30. }
  31.  
  32. 输出结果为:
  33. SuperClass() is construted.
  34. SubClass() is constructed.
  35. sub.i is: 20.0
  36. the i in SubClass: 20.0
  37. the i in SuperClass: 10

  我们很清楚,如果在子类中重新声明一个同样的print()函数,父类的print()函数就会被覆盖掉,这时print()输出的是在子类中定义的double i=20.0,所以对这种情况我没有讨论。

  从输出结果来看,通过子类SubClass的对象sub访问到的i的值为double i=20.0,然而通过子类对象调用在父类中定义的print(),打印的仍然是父类中的int i=10,如何解释这种情况?

  现在我们把SubClass进行修改:

  1. class SubClass extends SuperClass {
  2. public int i;
  3. SubClass(){
  4. i=20;
  5. System.out.println("SubClass() is constructed.");
  6. }
  7. public void printSub(){
  8. System.out.println("the i in SubClass: "+i);
  9. }
  10. }
  11.  
  12. /*测试结果为*/
  13. SuperClass() is construted.
  14. SubClass() is constructed.
  15. sub.i is: 20
  16. the i in SubClass: 20
  17. the i in SuperClass: 10

  我们看到,就算是在子类SubClass中声明了一个完全一样的i,通过子类对象调用在父类中定义的print(),打印的仍然是父类中的int i=10。说明了两点:子类仍然含有父类中的i,父类的方法不能操作子类中的变量。

  接下来,我再进行改动:

  1. class SubClass extends SuperClass {
  2. public int i;
  3. SubClass(){
  4. i=20;
  5. System.out.println("SubClass() is constructed.");
  6. }
  7. public void print(){
  8. System.out.println("the i in SubClass: "+i);
  9. }
  10. }
  11.  
  12. class TestDemo {
  13. public static void main(String[] args) {
  14. SubClass sub=new SubClass();
  15. System.out.println("sub.i is: "+sub.i);
  16. System.out.println("((SuperClass)sub).i is:"+((SuperClass)sub).i);
  17.  
  18. System.out.println("\n sub.print() is :");
  19. sub.print();
  20.  
  21. System.out.println("((SuperClass)sub).print() :");
  22. ((SuperClass)sub).print();
  23. }
  24. }
  25.  
  26. 输出结果:
  27. SuperClass() is construted.
  28. SubClass() is constructed.
  29. sub.i is: 20
  30. ((SuperClass)sub).i is:10
  31.  
  32. sub.print() is :
  33. the i in SubClass: 20
  34. ((SuperClass)sub).print() :
  35. the i in SubClass: 20

  改动后,子类父类中都有int i,他们的值不同;也都有完全一样的print()来打印i。看看结果,父类的i仍然存在子类的内存中,只是它被”隐藏“起来了,可以通过向上转型访问到。而父类中的print()方法,却访问不到了,被完全覆盖掉了。

Java 子类继承父类成员中的问题的更多相关文章

  1. java 子类继承父类成员变量的隐藏、实现方法的重写

    成员变量的隐藏和方法的重写 Goods.java public class Goods { public double weight; public void oldSetWeight(double ...

  2. java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数

    一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构

  3. Java子类对于父类中static方法的继承

    今天看到了Java中子类继承父类的一个相关讨论,在网上综合了各家的观点,写下了一篇简短的总结. 问题如下,在父类中含有staic修饰的静态方法,那么子类在继承父类以后可不可以重写父类中的静态方法呢? ...

  4. java子类和父类中静态块、非静态块、构造函数的执行顺序

    public class qqqq extends Parent{ public static void main(String[] args) { new Child(); } } class Pa ...

  5. 源码编译OpenJdk 8,Netbeans调试Java原子类在JVM中的实现(Ubuntu 16.04)

    一.前言 前一阵子比较好奇,想看到底层(虚拟机.汇编)怎么实现的java 并发那块. volatile是在汇编里加了lock前缀,因为volatile可以通过查看JIT编译器的汇编代码来看. 但是原子 ...

  6. java中子类实例化过程中的内存分配

    知识点: 子类继承父类之后,实例化子类时,内存中子类是如何分配内存的呢? 下面,自己会结合一个例子,解释一下,一个子类实例化过程中,内存是如何分配的 参考博客:http://www.cnblogs.c ...

  7. java对象在内存中的结构(HotSpot虚拟机)

    一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以 ...

  8. Java多态与C++中多态的实现

    大牛的文章,值得拜读http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/ 粘贴过来好多图片丢失了 /(ㄒoㄒ)/~~ 众所周知,多态是面向 ...

  9. 【转】成为Java顶尖程序员 ,看这11本书就够了

    成为Java顶尖程序员 ,看这11本书就够了 转自:http://developer.51cto.com/art/201512/503095.htm 以下是我推荐给Java开发者们的一些值得一看的好书 ...

随机推荐

  1. gcd表(欧几里得定理)

    题目:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=797 gcd表 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 ...

  2. C# WebServices 客户端服务端

    一.编写一个WebService 开发环境:VS2012 1.编写webservice阶段 打开VS2012,新建一个空的web应用程序,我这里用的Framework版本是4.5的 新建好web应用程 ...

  3. VNC连接Ubuntu 16.04桌面灰色的问题解决

        1.安装gnome apt-get install --no-install-recommends ubuntu-desktop gnome-panel gnome-settings-daem ...

  4. 前端性能之Chrome的Waterfall

    浏览器根据HTML中外连资源出现的顺序,依次放入队列(队列),然后根据优先级确定向服务器获取资源的顺序.同优先级的资源根据HTML中出现的先后顺序来向服务器获取资源. 瀑布中各项内容的含义: 排队: ...

  5. LC 656. Coin Path 【lock, Hard】

    Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The ...

  6. SAX解析示例代码和原理

    import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; ...

  7. SQL中group by使用

    多条重复记录,有一个字段可以进行区分,从重复的记录中取出其中一条,可利用group by字段 举例如下: 查询所有 查询地区中的最高分

  8. 《Javascript 语言精粹》 中 用到的一些代码 (1)

    var isNumber = function isNumber(value){ return typeof value === 'number' && isFinite(value) ...

  9. C基础知识(9):输入输出、文件读写

    输入输出 (1) getchar() & putchar() 函数: 读写字符. (2) scanf() 和 printf() 函数:根据提供的format来转换输入为其他数据类型,并根据提供 ...

  10. document.documentElement 和 document.body

    MDN : The Document.documentElement read-only property returns the Element that is the root element o ...