java 父类访问子类对象的实例变量 继承过程中的执行顺序
2014-10-09 10:33
921 查看
子类的方法可以访问父类的实例变量,子类可以获得父类的成员变量和方法,但弗雷德方法不能访问子类的实例变量,但是在极端情况下,也是可以访问的。
讲到这些问题,就涉及到继承时,当我们去创建一个类的时候,构造方法的执行顺序,将是很关键的一个问题,子类的先执行还是父类的先执行,构造函数和实例变量的初始化的执行顺序又是怎么样的呢?我们通过一段代码实例来讲解一些这个问题
执行完上面的程序将会打印出什么来呢,该段代码编译的时候,首先JVM要为两个类创建一个空间,这段空间将会用来保存该类中的一些类变量,然后当我们创建了一个Student对象,首先,开始执行时,为类里面的每一个实例变量分配一段内存,用来保存这些变量,这会开辟出两个空间来,分别用来保存这两个类中的实例变量,在这个时候是没有对其进行初始化的,只是为它分配好空间,等着来盛放数值。初始化的操作是在构造函数执行之前执行的,那么我们再来分析上面的代码,分配出两个空间之后,首先要执行的是父类的构造函数,执行到过程为 name =
"jiaojiao";然后是this.dispaly();
this现在的指向是什么呢,java中this表示的是当前正在初始化的对象,也就是Student的实例,所以当执行dispaly()方法的时候输出的就是Student类中的name实例变量,而此时Student类中并未执行对于实例变量的初始化操作,所以说输出的值是默认的值,也就是空。如果我们直接在Person类中加一行输出的代码,我们得到的值将是Person类中的实例变量的初始化的值。同时在这里又出现的问题就是this的编译类型和运行类型的问题,上面当其执行的时候调用的是当前正在初始化的对象,当变量编译时的类型和运行时的类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值是由声明该变量的编译类型决定的,但通过该变量调用方法时,是由其当前实际引用的对象来决定的。这也就很好的解释了上面的问题,首先第一个是调用的方法,所以变量调用的就是实例变量是当前正在被初始化的,然后直接调用的调用的时候,我们用的是当前对象中的,我们所说的父类调用子类方法,无非就是编译类型和运行类型之间的问题,产生了一种调用了子类的方法的错觉。
讲到这些问题,就涉及到继承时,当我们去创建一个类的时候,构造方法的执行顺序,将是很关键的一个问题,子类的先执行还是父类的先执行,构造函数和实例变量的初始化的执行顺序又是怎么样的呢?我们通过一段代码实例来讲解一些这个问题
class Person { private String name ="jiaojiao" ; public Person () { this.display (); }
public void display (){
system.out.println(name);
} } class Student extends Person { private String name = "jiaojiao"; public Student (){ } public void display (){ System.out.println(name); } } public Class Test { public void main(String []args){ new Student (); } }
执行完上面的程序将会打印出什么来呢,该段代码编译的时候,首先JVM要为两个类创建一个空间,这段空间将会用来保存该类中的一些类变量,然后当我们创建了一个Student对象,首先,开始执行时,为类里面的每一个实例变量分配一段内存,用来保存这些变量,这会开辟出两个空间来,分别用来保存这两个类中的实例变量,在这个时候是没有对其进行初始化的,只是为它分配好空间,等着来盛放数值。初始化的操作是在构造函数执行之前执行的,那么我们再来分析上面的代码,分配出两个空间之后,首先要执行的是父类的构造函数,执行到过程为 name =
"jiaojiao";然后是this.dispaly();
this现在的指向是什么呢,java中this表示的是当前正在初始化的对象,也就是Student的实例,所以当执行dispaly()方法的时候输出的就是Student类中的name实例变量,而此时Student类中并未执行对于实例变量的初始化操作,所以说输出的值是默认的值,也就是空。如果我们直接在Person类中加一行输出的代码,我们得到的值将是Person类中的实例变量的初始化的值。同时在这里又出现的问题就是this的编译类型和运行类型的问题,上面当其执行的时候调用的是当前正在初始化的对象,当变量编译时的类型和运行时的类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值是由声明该变量的编译类型决定的,但通过该变量调用方法时,是由其当前实际引用的对象来决定的。这也就很好的解释了上面的问题,首先第一个是调用的方法,所以变量调用的就是实例变量是当前正在被初始化的,然后直接调用的调用的时候,我们用的是当前对象中的,我们所说的父类调用子类方法,无非就是编译类型和运行类型之间的问题,产生了一种调用了子类的方法的错觉。
相关文章推荐
- Java对象的构造过程---子类继承父类时(非)静态块及构造函数等的执行顺序
- OC 继承子类对象调用方法机制 子类对象访问父类中的实例变量
- OC中继承子类对象调用方法机制 子类对象访问父类中的实例变量
- Java父类与子类中静态代码块 实例代码块 静态变量 实例变量 构造函数执行顺序
- OC中继承子类对象调用方法机制 子类对象访问父类中的实例变量
- Java父类与子类中静态代码块 实例代码块 静态变量 实例变量 构造函数执行顺序
- Java子类继承父类,构造方法的执行顺序问题
- java中 静态成员、实例成员、构造方法在子类和父类中的执行顺序
- Java子类继承父类,静态代码块、普通代码块、构造代码块的执行顺序
- Java-关于子类是否继承了父类的private实例变量
- 关于java中子类,父类中,静态代码块: staic{},动态代码块:{},构造方法,类属性,对象属性等执行顺序做个总结:
- java父类子类中静态块非静态块构造方法的执行顺序和继承
- [C#]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- Java 构造器之访问子类对象的实例变量
- Java继承中父类子类构造方法、静态代码块、非静态代码块的执行顺序
- Java之访问子类对象的实例变量
- java继承中父类和子类静态、非静态代码块,构造函数,静态方法的执行顺序
- Java 中子类继承父类,执行顺序
- [C++]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- JAVA基础-子类继承父类实例化对象过程