欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

覆盖了父类的成员变量引发的问题

程序员文章站 2022-05-29 21:37:18
...

    this代表什么呢?代表当前类的某个对象?请看下面这段代码:

package cn.com.wg.task01;
 
public class CallOrder {
   class Base {
      private int i = 2;
      public Base() {
         System.out.println(this);
         this.display();
      }
      public void display() {
         System.out.println("Base " +this.i);
      }
   }
 
   class Child extends Base {
      private int i = 22;
      public Child() {
         System.out.println(this);
         i = 222;
      }
      public void display() {
         System.out.println("Child " + i);
      }
   }
 
   public void init() {
      new Child();
   }
 
   public static void main(String[] args) {
      new CallOrder().init();
   }
}

输出结果是什么呢?

cn.com.wg.task01.CallOrder$Child@d0da1d8
Child 0
cn.com.wg.task01.CallOrder$Child@d0da1d8

 

此时,子类和父类构造函数的this代表同一个对象!!!this理解为代表调用该方法的那个对象更合适。

我们知道子类的构造函数会调用父类的构造函数(如果没有显示的调用,默认隐式调用无参的构造函数),所以在该程序中,父类的无参构造函数会在子类的构造函数中调用。因此,子类和父类构造函数的this代表同一个对象。

 

那么,输出的“Child 0”怎么解释呢?这里就牵涉到JVM的内存分配了。下面简单介绍。

当JVM遇到new关键字时,就会开始在内存中给对象分配空间。一个简单的java对象的在内存中包括三个部分:对象头、变量、填充区域。new结束后,变量域是初始化后的值(即boolean为false,char为'\0',其他基本类型为0,对象为null)。当遇到new后的类名是才开始执行我们代码中的构造函数。

 

这是用javap看到的class文件中Child的构造函数内容:

 

覆盖了父类的成员变量引发的问题
            
    
    博客分类: Java java继承覆盖变量
 

这是Base类的构造函数:

覆盖了父类的成员变量引发的问题
            
    
    博客分类: Java java继承覆盖变量

在Base类的构造函数中调用display方法,显然是调用在Child里写的display方法,i也是Child里的i。但是Child中,i的初始化是在调用display之前完成的,所以此时i=0;

 

如果我们把Child里的display去除,会输出什么呢?“Base 2”。此时调用的display肯定是Base里的了,而且i的初始化在调用display之前,而且这个i是在Base中声明的。那么,问题来了,Child对象中有几个i变量呢?“2个”。

 

 

这些问题全是由子类中覆盖了父类的成员变量造成的,所以不要轻易覆盖父类的成员变量,而且很少一定要这么做

 

 

  • 覆盖了父类的成员变量引发的问题
            
    
    博客分类: Java java继承覆盖变量
  • 大小: 59.5 KB
  • 覆盖了父类的成员变量引发的问题
            
    
    博客分类: Java java继承覆盖变量
  • 大小: 10.3 KB