成员变量是类时与继承类中父类在子类中内存情况

来源:互联网 发布:淘宝上配眼镜靠谱么 编辑:程序博客网 时间:2024/06/03 20:30

 

      之前总是不明白为什么当成员变量时一个类时,这个变量的使用需要用new()来构造才能使用,而在继承类中,父类对象却可以直接参考子类对象。这些天终于又明白了。。

     这是因为: 当成员变量是一个类时,这样的的成员变量实际上是一个“对象变量”,所以必须另外建立此“对象变量”所参考的“对象实体”。

     而在继承类中,无论子类从父类继承来的成员无论是可见度如何,在子类中都会拥有一份父类的实体.所以父类对象可以直接参考子类的实体对象了。不过这里得注意方法的覆盖以及域的隐藏所参考的实体有所不同。我觉得可以记住两点:(1)当使用“对象.成员变量”时,可以根据“对象变量”的类型,来判断会使用哪个类的“成员变量”,例如下面例子2中,obj3是A2类型,所以obj3.var 所存取的是A2类刑的var1,(尽管该对象变量是参考其子类的实体,且子类里也再定义了var1)。(2)当使用“对像.方法”时。是根据“对象实体”的类型,来判断唤起哪个类中的方法实现。具体也是见例子2.

 

    其实这些真的画出内存图特别好理解。之前有很多总是不明白为什么是这样用,现在感觉都很清晰了。

具体可见下面的例子:

package Keytry;

import java.lang.*;
public class classMenbers
{
   //以下两个都是成员变数
   int num;  //primitive type 的变量
   Boolean ifPassed; //Boolean 类类型的对象变量
  
   public static void main(String[] para)
   {
      classMenbers obj = new classMenbers(); //构造 obj 对象的实体
      System.out.println( obj.num ); //初始化为 0
      System.out.println( obj.ifPassed ); //初始化为 null
        /* obj.ifPassed 之值为 null,
           表示 obj.ifPassed 对象尚未参考一个对象实体。
           也就是 new classMenbers(),
           并不会自动构造 ifPassed 成员的对象实体。 */        
      //System.out.println( obj.ifPassed.booleanValue() );
        //上一行会有执行错误
     
      obj.num = 100;
      System.out.println( obj.num );
     
      obj.ifPassed = new Boolean(true);
                     //必须构造 obj.ifPassed 的对象实体             
      System.out.println( obj.ifPassed.booleanValue() );
                       /* obj.ifPassed 已有对象实体,
                          故可使用它的 booleanValue() 方法。*/     
   }
}

2

package Keytry;

import java.lang.*;
public class overRide
{
   public static void main(String[] para)
   {
      A2 obj1 = new A2();
      obj1.showVar1();
      System.out.println( "obj1.var1 =" + obj1.var1 );     
      System.out.println("=================================");
      B2 obj2 = new B2();
      obj2.showVar1();
      System.out.println( "obj2.var1 =" + obj2.var1 );
      System.out.println("=================================");
      A2 obj3 = new B2(); 
      obj3.showVar1();
      System.out.println( "obj3.var1 =" + obj3.var1 );
      /* 父类对象,可参考子类对象实体,
       * 因为子类对象实体内含有父类的实体。
       * 而 obj3 使用的 showVar1(),
       * 会是 B2 类 Override 后的 showVar1()。*/
   }
}

class A2
{
   int var1 = 100;
   protected void showVar1()
   {
      System.out.println("A2 定义的 showVar1() var1 = " + var1);
   }
}

class B2 extends A2
{
   double var1 = 1111.111;
   /* 隐藏继承而来的 int var1
    * 在 B2 类内,var1 指的是 B2 定义的 double var1。 */
  
   public void showVar1()
   { //Override 时,封装等级允许扩大
      System.out.println("B2 定义的 showVar1() var1 = " + var1);
   }    
}

原创粉丝点击