继承相关知识
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承相关知识相关的知识,希望对你有一定的参考价值。
1.在构造器中,super调用用于显示调用父类构造器,this调用用于显示调用本类中另一个重载的构造器。二者只能取其一,且最多只能调用一次。
2.类变量的赋值-->是在构造器中super()或this()之后。
1 public class A{ 2 private int a = 1; 3 { 4 a = 2; 5 } 6 public A(){ 7 a = 4; 8 } 9 { 10 a = 3; 11 } 12 }
以上代码在JVM中的执行为:
public class A{ private int a; public A(){ super(); a = 1; a = 2; a = 3; a = 4; } }
以下在”疯狂JAVA突破程序员基本功的16课“中的案例:
class Base{ private int i = 2; public Base(){ this.display(); } public void display(){ System.out.println(i); } } class Derived extends Base{ private int i = 22; public Derived(){ i = 222; } public void display(){ System.out.println(i); } } public class Test { public static void main(String[] args) { new Derived(); } }
以上代码最终结果为0。
在new Derived()的时候,此对象拥有两个i的实例变量,一个是父类Base的,一个是子类Derived的,而调用父类构造方法的时候,this.display()其实是子类的方法,而此时i还未赋值,为0,谷输出结果为0。
如此时在Base类中this.display();代码之前加一句System.out.println(this.i); 最终结果为2,0
那么,这个this代表的是什么呢?
当this在构造器中时,this代表正在初始化的Java对象。在代码中this的对象应该是Derived啊,那么为什么this.i的值是2呢?这是因为<--当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。但通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际引用的对象来决定。-->
也就是说,this.i时对象为声明该变量的类型(Base),而调用方法时则是Derived。
对于这个还有一个例子可以看看:
1 class B{ 2 int count = 2; 3 public void display(){ 4 System.out.println(this.count); 5 } 6 } 7 class D extends B{ 8 int count = 20; 9 public void display(){ 10 System.out.println(this.count); 11 } 12 } 13 public class Test{ 14 15 public static void main(String[] args) { 16 B b = new B(); 17 System.out.println(b.count); 18 b.display(); 19 20 D d = new D(); 21 System.out.println(d.count); 22 d.display(); 23 24 B bd = new D(); 25 System.out.println(bd.count); 26 bd.display(); 27 28 B d2b= d; 29 System.out.println(d2b.count); 30 d2b.display(); 31 } 32 }
对于b,d来说和简单,输出分别为2,2 20,20
对于db,bd.count的值为2,而bd.display()则输出20,原因则在上面加粗
对于d2b,其实与d指向同一个对象(如果输出 d2b== d 结果为true),d.count的值为20,那么d2b的值也为20么?不是的,这时d2b.count的值为2(调用display方法输出20)。也就是说,d2b指向的对象中存放着两块内存地址。同时也说明了Java继承在处理成员变量和方法时是有着不同的,变量是看编译时的对象,方法是看运行时的对象。
内存的话,当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为其父类中定义的实例变量分配内存(包括间接父类),哪怕变量名相同(只不过会隐藏)。为了在子类方法中使用父类中定义的被隐藏的变量,被覆盖的方法,可以使用super关键字。
类变量会在类初始化的阶段被初始化,是属于类的,可以直接通过类.变量名来调用,在子类中也可通过super.变量名来调用(最好使用类.变量名)。
以上是关于继承相关知识的主要内容,如果未能解决你的问题,请参考以下文章
前端知识体系-JS相关深入理解JavaScript原型(继承)和原型链