zoukankan      html  css  js  c++  java
  • 访问子类对象的实例变量

     1 public class BaseTest {
     2 
     3     public static void main(String[] args)
     4     {
     5         new Derived(); // 1
     6     }
     7 }
     8 
     9 class  Base
    10 {
    11     private int i =2;
    12     
    13     public Base()
    14     {
    15         this.display();
    16     }
    17     public void display()
    18     {
    19         System.out.println("Base i is:"+i);
    20     }
    21 }
    22 
    23 class Derived extends Base
    24 {
    25     private int i =22;
    26     public Derived()
    27     {
    28         i =222;
    29     }
    30     public void display()
    31     {
    32         System.out.println("Derived i is :"+i); //2
    33     }
    34     
    35 }

    运行结果:

      Derived i is :0

    分析:new Derived();

    系统会自动调用Base类中无参数的构造器来进行初始化。

    构造器只是负责对Java对象实例变量执行初始化(也就是赋初始值),在执行构造器代码之前,该对象所占的内存已经被分配下来,这些内存里值都是默认值 0或者false,

    或者null(引用类型的变量)。

    当执行到1时,系统先为Derived对象分配内存空间,此时需要分配两块内存,用于存放Dericed对象的两个i实例变量,这两个i 一个属于Base定义的i实例变量,一个属于Derived定义的i实例变量。此时值都是0;

    接下来在执行Derived类的构造器之前,先执行Base类的构造器。this.display();

    这里的this代表谁?---当this在构造器中时,this代表正在初始化的java对象,此时的情况是:this位于Base()构造器中,但是这些代码实际在Derived()构造器内执行---是Derived()构造器隐式调用了Base()构造器的代码。此时 this.i 应该是2,this虽然代表Derived对象,但它却位于Base构造器中,它的编译时类型是Base,而它实际引用一个Derived对象。

    当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定,但通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际所引用的对象所决定。

    因此在调用this.display()时,则实际变现出Derived对象的行为,即输出 Derived i is: 0.

    程序创建一个子类对象时,系统不经会为该类中定义的实例变量分配内存,也会为其父类中定义的所有实例变量分配内存,及时子类定义了与父类中同名实例。

    public class Apple extends Fruit {
    
        @Override
        public void info()
        {
            System.out.println("Apple方法");
        }
        public void AccessSuperInfo()
        {
            super.info();
        }
        
        public Fruit getSuper()
        {
            return super.getThis();
        }
        
        String color="红色";
        public static void main(String[] args)
        {
            Apple a =  new Apple();
            Fruit f = a.getSuper();
            System.out.println("a 和f 所引用的对象是否相同"+(a==f));
            System.out.println("访问a所引用的对象的color实例变量:"+a.color);
            System.out.println("访问f所引用的对象的color实例变量:"+f.color);
            a.info();
            f.info();
            a.AccessSuperInfo();
            
        }
    }
    
    class Fruit
    {
        String color ="未确定颜色";
        public Fruit getThis()
        {
            return this;
        }
        public void info()
        {
            System.out.println("Fruit方法");
        }
    }

    运行结果:

    a 和f 所引用的对象是否相同true
    访问a所引用的对象的color实例变量:红色
    访问f所引用的对象的color实例变量:未确定颜色
    Apple方法
    Apple方法
    Fruit方法

  • 相关阅读:
    UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)
    SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并
    洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
    HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模
    HDU 3183.A Magic Lamp-区间找最小值-RMQ(ST)
    HDU 1231.最大连续子序列-dp+位置标记
    牛客网 牛客练习赛43 F.Tachibana Kanade Loves Game-容斥(二进制枚举)+读入挂
    CodeForce-811B Vladik and Complicated Book(水题)
    POJ1426——Find The Multiple (简单搜索+取余)
    POJ——3278 Catch That Cow(BFS队列)
  • 原文地址:https://www.cnblogs.com/happinessqi/p/3439435.html
Copyright © 2011-2022 走看看