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方法

  • 相关阅读:
    MYSQL中数据类型介绍
    怎么评估软件上线标准
    文件安全复制之 FastCopy
    强烈推荐美文之《从此刻起,我要》
    浅谈软件测试与墨菲定律
    夜神模拟器--安卓模拟神器
    RoadMap:如何创建产品路线图
    利用Python爬虫刷店铺微博等访问量最简单有效教程
    MySQL 数据库中删除重复数据的方法
    如何测试一个杯子
  • 原文地址:https://www.cnblogs.com/happinessqi/p/3439435.html
Copyright © 2011-2022 走看看