黑马程序员技术交流社区

标题: 关于继承加载函数的顺序问题 [打印本页]

作者: 刘源    时间: 2012-8-2 11:14
标题: 关于继承加载函数的顺序问题
本帖最后由 刘源 于 2012-8-2 19:46 编辑

问题已经解决”。

class classC extends classA
{
public classC()
{
         System.out.println("C");
        }
}


class classA
{
public classA()
{
         System.out.println("A");
        }
}


class classB extends classC
{
public classB()
{
  System.out.println("B");
}
}


public class Test
{
public static void main(String args[])
{
  System.out.println("Main");
  classB c = new classB();
}
}
打印结果为:
Main
A
C
B
先是主函数能看明白,后面的为什么不是B而是A啊,就不懂了。有高手分析下。

作者: pphdsny3    时间: 2012-8-2 11:29
给你看看这些代码,看明白了,你也就懂了
  1. package com.hf.scjp.constructor;

  2. public class Parent1 {
  3. public static StaticTest stat=new StaticTest(1L);
  4. static {
  5.   
  6.     System.out.println("in parent1 static code …… ");
  7. }
  8.    public Parent1(){
  9.     System.out.println("in parent1 constructor …… ");
  10.    
  11.    }
  12. }







  13. package com.hf.scjp.constructor;

  14. public class Son1 extends Parent1 {
  15. public static StaticTest stat=new StaticTest(1);
  16. static {
  17.   
  18.     System.out.println("in Son1 static code …… ");
  19. }
  20. public Son1(){
  21.      System.out.println("in Son1 constructor …… ");
  22.      
  23.     }
  24. public Son1(int s){
  25.      System.out.println("in Son1 constructor with param: int");
  26.      
  27.     }

  28. }


  29. package com.hf.scjp.constructor;

  30. public class GrandChild1  extends Son1{
  31. public static StaticTest stat=new StaticTest();
  32. static {
  33.   
  34.     System.out.println("in GrandChild1 static code …… ");
  35. }
  36. public GrandChild1(){
  37.      System.out.println("in GrandChild1 constructor …… ");
  38.      
  39.     }
  40. public GrandChild1(String s){
  41.      System.out.println("in GrandChild1 constructor with param: String");
  42.      
  43.     }
  44. public GrandChild1(int s){
  45.      super(s);
  46.      
  47.      System.out.println("in GrandChild1 constructor with param: int");
  48.      
  49. }
  50. public GrandChild1(long s){
  51.      this((int)s);
  52.      
  53.      System.out.println("in GrandChild1 constructor with param: long");
  54.      
  55. }
  56. public static void main(String[] args){
  57.   GrandChild1 GrandChild1=new GrandChild1("");
  58.    System.out.println("\n\r");
  59.   
  60.   GrandChild1 GrandChild2=new GrandChild1(3);
  61.   
  62.    System.out.println("\n\r");
  63.   GrandChild1 GrandChild3=new GrandChild1(3L);
  64. }
  65. }

  66. public class StaticTest {
  67.     public StaticTest(){
  68.      System.out.println("in StaticTest constructor param:  ");
  69.      
  70.     }
  71.     public StaticTest(int i){
  72.      System.out.println("in StaticTest constructor param:int  ");
  73.      
  74.     }
  75.     public StaticTest(long l){
  76.      System.out.println("in StaticTest constructor param:long  ");
  77.      
  78.     }
  79. /**
  80.   * @param args
  81.   */
  82. public static void main(String[] args) {
  83.   // TODO 自动生成方法存根

  84. }

  85. }

  86. //这是一个三个类之间的继承关系继承:在孙子类中定义了main并创建三个孙子类对象,分别调用不同的构造函数,执行结果如下:
  87. in StaticTest constructor param:long  
  88. in parent1 static code ……
  89. in StaticTest constructor param:int  
  90. in Son1 static code ……
  91. in StaticTest constructor param:  
  92. in GrandChild1 static code ……
  93. in parent1 constructor ……
  94. in Son1 constructor ……
  95. in GrandChild1 constructor with param: String



  96. in parent1 constructor ……
  97. in Son1 constructor with param: int
  98. in GrandChild1 constructor with param: int



  99. in parent1 constructor ……
  100. in Son1 constructor with param: int
  101. in GrandChild1 constructor with param: int
  102. in GrandChild1 constructor with param: long
复制代码
这说明:
1 类中的静态对象先于static{}执行
2  static{}中的代码是在构建类对象之前执行的
3 构造子类的时候是按照先父后子的顺序执行的
4 如果在子的构造函数中并没有使用显式的调用父类的构造函数(使用super),则执行无参构造函数。
5 如果使用this(),则会先调用this(),再调用下面的代码(此时父类别的默认构造函数不再执行,而会根据执行this()执行相应的父构造函数)
说的自己都晕了,还是看代码来的简单容易
作者: hello world    时间: 2012-8-2 12:03
子类继承父类,当创建子类对象时需要先创建父类对象,当你new B()对象时,默认在B类的构造函数中的第一行调用了super(),也就调用了父类的构造函数,同理调用父类的父类,所谓有父亲才有儿子的道理。所以执行的结果就是这个样子。但是要切记构造函数不能继承,只能在子类的构造函数中隐式或显示的调用(可以使用super关键字)
作者: 尤洋    时间: 2012-8-2 14:31
  以classA,classB,classC命名有点让人蛋疼啊,容易让人弄混,其实原理很简单,就是B-->C-->A的继承关系,如图所示,点开看看就知道了
在输出main后 最后输出结果由上往下是ACB
作者: 黑马黄宏强    时间: 2012-8-2 14:47
因为构造函数如果第一跳条语句没有写this或super,系统会默认添加一天super()
分析:System.out.println("Main");
  classB c = new classB();
首先输出打印 Main
然后创建一个B类对象,使用的是无参构造函数
public classB(){  System.out.println("B"); }
它的第一条语句不是this也不是指定的super,所以系统默认生成super();
执行super()找B的直接父类,super()没执行完后面的语句是不会运行,然后找到他的夫类C类,调用C类的无参构造函数,
public classC(){  System.out.println("C"); }
它的第一条语句也不是this和指定的super,所以系统默认生成super();执行super()找C的直接父类,调用A类的无参构造函数
public classA(){  System.out.println("A"); }
它的第一条语句也不是this和指定的super,所以系统默认生成super();执行super()找A的直接父类,A类无直接父类,默认继承了Object类
这里就就会完成A类的构造,输出A, A类执行完成后C类执行后续操作 输出C C构造完成后B类也执行后面操作 输出B
所以最终的打印结果是:
Main
A
C
B







作者: 黑马黄宏强    时间: 2012-8-2 14:48
好几个错别字{:soso_e110:}




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2