输出结果为
12
12
13
10
虚拟机执行步骤:
然后将B类的实例对象地址赋值给引用变量b。
下面解决几个问题:
1.为什么super.x输出是12?父类的x没有被修改啊?a.hh()的输出可以证明
答:B继承A的,创建B对象的时候会执行B的构造方法,图中B的构造方法未写出,自动调用无参构造,
public B(){
super();//自动调用A类构造方法
...
}
同时由于A中自动添加无参构造方法,也会对A的构造函数进行调用,创建隐含的A类对象aa,对象aa中为变量x分配了一个引用,aa和b都指向这个引用,x=x+2修改了引用里x的值,super.x也指向这个引用,所以输出的是修改后x的值,记住super.x指的是父类对象aa的x值 而不是父类的x值 所以super.x表示aa对象的x值 该值和bb的x值指向同一个引用。过程中创建的变量x、函数f()、hh()的引用同时给了父类和子类创建的对象,f()函数修改了x的值,即aa对象和bb对象指向的x修改了。。总的来说,super.x和bb.x是指向同一块内存地址的。
2.如果在Class B中添加int X,结果会是如何?
答:在原题中B类里面根本就没有定义 X, 所以你引用的也是父类的 那么当X=X+2的时候改变的也是父类对象的X 如果B类中 声明一个int X那么X变量被重写(覆盖),那么子类对象中对x的操作只会引起bb中x的值,父类对象aa中的X就不会是12 ,而是10。此时子类中的X变量和父类的X不存在引用关系。
3.为什么A a=new A();
a.hh()打印的是10 而不是13
答:之前对x的操作只改变了aa和bb中共享的x值,对类没有影响,new出一个新对象是按照类进行初始化的,所以x的初始值还是10
另外:类是一个抽象的概念,对象才是具体的,子类的动作只会影响到父类的对象,你父类的属性是不受影响的。
如都不是private 那么子类将覆盖父类field 子类中出现两个field 默认的是子类.field 访问父类field通过super.field
java中子类对父类属性方法的继承或者覆盖分类:
个人总结大致5种情况:
父子都有 父有子无 父无子有
1.最普通 父类有非private的field子类无field 直接继承 指向相同存储空间 this.field和super.field指向同一
2. 父类有field 但是private 子类无field 直接继承 但是field隐藏在子类不可见 无法访问子类field 理解为子类不存在field
3.父子都有field 父类field属性非pirvate 经典覆盖(重写) 无法继承父类field 默认用自己的 子类中有两个field空间 this.field和super.field分别执行子类field和父类field
4.父子都有field 但是父类pirvate 子类有父类private修饰的field变量 但是父类field不可见 只有自己的field可见 无法继承 无法重写 super.field出错 类似于第5种 子类中field纯属额外属性
5.父无field 子有field 额外附加属性方法