java中子类父类继承深入理解

  1. class Depend   
  2. {   
  3.     int 10;   
  4.     public Depend()   
  5.     {   
  6.         print();   
  7.         20;   
  8.     }   
  9.   
  10.     void print()   
  11.     {   
  12.         System.out.println("Depend=> " i);   
  13.     }   
  14. }   
  15.   
  16.   
  17. public class Qdb extends Depend   
  18. {   
  19.     int 30;   
  20.     public Qdb()   
  21.     {   
  22.         print();   
  23.         super.print();   
  24.         40;   
  25.     }   
  26.   
  27.     void print()   
  28.     {   
  29.         System.out.println("Target=> " i);   
  30.     }   
  31.   
  32.     public static void main(String[] args)   
  33.     {   
  34.         new Qdb();   
  35.     }   
  36.  

 其结果是:

Target=> 0
Target=> 30
Depend=> 20

 

为什么呢?

我们顺着初始化的顺序来说
首先程序从main方法开始执行,new Qdb(),这句话就是要new一个Qdb的对象,根据对象初始化的顺序,初始化子类之前必须要初始化父类,所以此时一系列的调用开始了
1,调用Qdb的父类Depend类的构造函数,在调用构造函数之前,成员变量是先于构造函数初始化的,这个时候Depend里面的i已经有值了,它的值就是10,在Depend构造函数里面,我们看到的第一句是:print方法,这个print方法我们要注意,它在Depend的子类也定义了,并且此次初始化是由子类Qdb发起的,所以实际上这个print方法调用的是Qdb里面定义的print,而这个时候有意思的事情就出现了,此时子类还没有出生呢,因为这个时候父类才正在构造之中,所以子类中此时的i还是0,而print正好打印出的是子类的i,所以第一次输出是0;
2,父类调用完子类的print后,把父类的i赋了值20,此时父类已经完全被构造出来了,马上就要开始构造子类了.
3,同理,在调用子类的构造函数之前,子类的i被赋了初值30,然后进入子类的构造函数,此时调用的也是print,这个就非常好理解了,这个print肯定是子类自己的print方法了,此时i已经构造好,当然,此时输出的值是30;
4,下一句super.print(),这句话显示的调用了父类的print方法,而此时父类的i已经在父类的构造函数里面改为20了,所以此次调用输出20.
5,然后再把子类的i的值设为50.

在以上过程中,如果掌握好了类的初始化顺序,是比较容易知道输出结果的.还有一点要记住,JAVA里面的方法是动态绑定的,而成员却是静态绑定的.父类里面调用的print之所以会输出0,就是因为print实际上调用的是子类的print,因为整个这场调用都是由new Qdb()这句话产生的.

 

接着再看下面的:

Java代码  复制代码
  1. class {   
  2.     int 10;   
  3.     static {   
  4.         System.out.print("1");   
  5.     }   
  6.   
  7.     public A() {   
  8.         System.out.print("2");   
  9.     }   
  10.        
  11.        
  12. }   
  13.   
  14. class extends {   
  15.     int 20;   
  16.     static {   
  17.         System.out.print("a");   
  18.     }   
  19.   
  20.     public B() {   
  21.         System.out.print("b");   
  22.     }   
  23.        
  24.        
  25. }   
  26.   
  27. public class Heloo {   
  28.     public static void main(String[] arge) {   
  29.         System.out.println(");   
  30.         ab new B();   
  31.         System.out.println(");   
  32.         ab new B();   
  33.     }   
  34.  

 结果是:

1a2b
2b


原因:

这个是类的初始化顺序问题
1、类只有在使用New调用创建的时候才会被JAVA类装载器装入
2、JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。
先初始化父类的静态代码--->初始化子类的静态代码-->
初始化父类的非静态代码--->初始化父类构造函数--->
初始化子类非静态代码--->初始化子类构造函数
3、创建类实例时,首先按照父子继承关系进行初始化
4、类实例创建时候,首先初始化块部分先执行,然后是构造方法;然后从
本类继承的子类的初始化块执行,最后是子类的构造方法
上例中类A类B都有静态代码static


从main函数开始:
System.out.println(" ");
输出空格
A ab = new B();
声明为类A但初始化为类B
因为编译器是从左向右进行的,所以先是A ab;
执行System.out.print("1"); 因为没有new A();
所以不执行类A的构造函数.那为什么会输出2呢?
是因为B类是继承A类的,所是在执行new B();
的时候,执行顺序是初始化System.out.print("a");
然后先父类后子类,static代码只执行一次(已执行过);
执行System.out.print("2");
执行System.out.print("b");
执行System.out.println(" ");
之后是ab = new B(); A,B中的static都已被执行过,
所以只执行构造函数,因B类有父类A,所以先执行A 类的构
造函数System.out.print("2");
再执行B类的构造函数
System.out.print("b");

 

这下该明白了吧。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值