黑马程序员技术交流社区

标题: 请哪位大侠举例给我阐述一下构造器的执行顺序。 [打印本页]

作者: 1315626724    时间: 2012-5-26 18:28
标题: 请哪位大侠举例给我阐述一下构造器的执行顺序。
近两天看继承,多态,蒙了。构造器的执行顺序搞得我疯了都。请求帮忙!!
作者: xieshuhua    时间: 2012-5-26 18:53
类的构造函数 接受参数的数量和类型不能全部相同,所以当输入一定的参数创建类时,只会运行一个对应的类中的构造函数。不存在执行顺序的问题
如下代码所示:
  1. public class cw{
  2. public static void main(String[] args){
  3. cla1 cl=new cla1("执行2");
  4. }
  5. }
  6. class cla1{
  7. String x;
  8. cla1(){System.out.println("执行1");};
  9. cla1(String x){
  10. this.x=x;
  11. System.out.println(x);
  12. }
  13. }
复制代码

运行效果.png (1.63 KB, 下载次数: 89)

运行效果.png

作者: suiabing    时间: 2012-5-26 19:06

作者: 黄克帅    时间: 2012-5-26 19:17
本帖最后由 黄克帅 于 2012-5-26 19:20 编辑

子类中的所有构造函数,都会默认调用父类的无参构造函数,因为在子类所有构造函数的第一行有隐式的代码:super();
如果父类中定义了有参的构造函数,则必须在子类中显式的掉用父类的有参构造函数,或者在父类中添加显式的无参构造函数。不然会报错。 因为这个时候父类系统默认的无参数构造函数已经不存在了
当然也可以在子类中的第一行手动用this语句来访问子类的构造函数,但是子类中至少有一个构造函数访问父类的构造函数。

public class Person {
        public int age;
        public String name;
        Person() {
                System.out.println("打印父类无参数构造函数");
        }

        Person(int age) {

                this.age = age;
                System.out.println("打印父类有一个参数构造函数");
        }
        
        public Person(int age, String name) {
               
                this.age = age;
                this.name = name;
                System.out.println("打印父类两个参数的构造函数");
        }

}

public class Student extends Person {
        private int age;
        public String name;

        Student() {
                // 这里有一行隐藏代码super();
                System.out.println("打印子类无参数构造函数");
        }

        Student(int age) {
                // 这里有一行隐藏代码super(); 当然手动指定了父类的构造函数,就不存在了
                super(age); // 通过super指定访问父类的构造函数
                this.age = age;
                System.out.println("打印子类有一个参数构造函数");
        }

        public Student(int age, String name) {
                // 这里有一行隐藏代码super(); 当然手动指定访问子类自己的构造函数,就不存在了
                this(age);// 通过this语句来指定访问子类自己的构造函数,但是不管怎么样都会有一个构造函数访问父类的构造函数
                this.age = age;
                this.name = name;
                System.out.println("打印子类两个参数的构造函数");
        }

}

public class Test {
        public static void main(String[] args) {
                 Student s = new Student();
                // 这里执行后打印 打印父类无参数构造函数
                // 打印子类无参数构造函数
                 Student s1 = new Student(1);
                // 这里执行后打印 打印父类有一个参数构造函数
                // 打印子类有一个参数构造函数
                Student s2 = new Student(1, "zhansan");
                // 这里执行后打印 打印父类有一个参数构造函数
                // 打印子类有一个参数构造函数
                // 打印子类两个参数的构造函数

        }

}
作者: 黑马11期李项京    时间: 2012-5-26 19:19
类初始化时构造函数调用顺序:
(1)初始化对象的存储空间为零或null值;
(2)调用父类构造函数;
(3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
(4)调用本身构造函数。
例子:
public class Dollar extends Money{
Rmb r=new Rmb();

public Dollar(){

System.out.println("Dollar is construct!");

}
public static void main(String[] args){

new Dollar();

}
}
class Money{
public Money(){
System.out.println("Money is construct");
}
}
class Rmb{
public Rmb(){
System.out.println("RMB is construct");
}
}
输出结果:
Money is construct
RMB is construct
Dollar is construct!
作者: 徐炯    时间: 2012-5-27 01:01
类初始化时构造函数调用顺序:
(1)初始化对象的存储空间为零或null值;
(2)调用父类构造函数;
(3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
(4)调用本身构造函数。



给你提供个经典代码,希望能帮到你!

public class MS_Extends {

public static void main(String[] args) {
  //A a = new A();
//  B b = new B();
  A a = new B();
  a.Run();
}

}

class  A{

public static int a = 0;
public int b = 0;

static{
  System.out.println("■父类 - 静态初始块 - 位置是构造函数前");
}

{
  System.out.println("■父类 - 普通初始块 - 位置是构造函数前");
}

public void Run(){
          System.out.println("■父类 - 普通函数");
         }
public A(){
  System.out.println("■父类 - 构造函数");
}

static{
  System.out.println("■父类 - 静态初始块 - 位置是构造函数后");
}

{
  System.out.println("■父类 - 普通初始块 - 位置是构造函数后");
}
}

class  B extends A{

public static int a = 0;
public int b = 0;

static{
  System.out.println("◆子类 - 静态初始块 - 位置是构造函数前");
}

{
  System.out.println("◆子类 - 普通初始块 - 位置是构造函数前");
}
public void Run(){
          System.out.println("◆子类  - 普通函数");
         }
public B(){
  System.out.println("◆子类 - 构造函数");
}
public B(int c){
          System.out.println("◆子类 - 构造函数b");
         }
static{
  System.out.println("◆子类 - 静态初始块 - 位置是构造函数后");
}

{
  System.out.println("◆子类 - 普通初始块 - 位置是构造函数后");
}
}


输出结果:
■父类 - 静态初始块 - 位置是构造函数前
■父类 - 静态初始块 - 位置是构造函数后
◆子类 - 静态初始块 - 位置是构造函数前
◆子类 - 静态初始块 - 位置是构造函数后
■父类 - 普通初始块 - 位置是构造函数前
■父类 - 普通初始块 - 位置是构造函数后
■父类 - 构造函数
◆子类 - 普通初始块 - 位置是构造函数前
◆子类 - 普通初始块 - 位置是构造函数后
◆子类 - 构造函数
◆子类  - 普通函数




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