构造函数使用心得

来源:互联网 发布:中企动力域名查询 编辑:程序博客网 时间:2024/05/24 02:54

    今天看到设计模式中的桥梁模式,有地方不理解,原来是构造函数的问题,下面将构造函数的使用写明。

     1、对于一个类,如果显示写明自己的构造函数,则系统不再添加默认的无参构造函数;如果不写构造函数,则系统会默认添加无参构造函数。

     2、在Java中,子类的构造过程中,必须 调用其父类的构造函数
是因为有继承关系存在时,子类要把父类的内容继承下来,通过什么手段做到的?
这样:
当你new一个子类对象的时候,必须首先要new一个父类的对像出来,这个父类对象位于子类对象的内部,
所以说,子类对象比父类对象大,子类对象里面包含了一个父类的对象,这是内存中真实的情况.

构造方法是new一个对象的时候,必须要调的方法,这是规定,要new父类对象出来,那么肯定要调用其构造方法,所以
第一个规则:子类的构造过程中,必须 调用其父类的构造方法。

     3、一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法,所谓默认的构造方法,就是没有参数的构造方法,但是如果你自己写了构造方法,那么编译器就不会给你添加了

所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是在子类构造方法中我们并没有显示的调用基类的构造方法,就是没写,如:super(); 并没有这样写,但是

第二个规则:如果子类的构造方法中没有显示的调用基类构造方法,则系统默认调用基类无参数的构造方法

注意:如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有默认无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数。

      例子:

提示错误:Implicit super constructor Circle()is undefined for default constractor .Must define an explicit constructor.

比如 如果子类Cyliner的构造函数写成
Cyliner(.../*参数略过*/){
  //没有确实使用super指定调用父类的哪个构造函数的话 就会默认调用父类的无参构造函数
}
而一般的 如果我们定义的一个类没有定义任何的构造函数的话 那么运行时会自动的为这个类设定一个默认的 无参数的构造子 但是 如果你定义了其它的构造子的话 就不在自动生成这个默认构造子了
就像是
class A{
  public A(int i){ //这里定义了一个构造函数 所以 就不会有默认构造子
  }
}

class B extends A{
  /*
  public B(int i){
  // 你这里没有指定要调用super(i)的话 就会默认去找A的无参数的构造子 但是 这个无参的构造函数是不存在的 所以就会抛出刚才的
  // 那个异常
  }
  */
  public B(int i){
  super(i); //这样就是对的了
  }
}

下面举一个例子说明一下构造方法,静态代码块,普通方法的调用顺序:


public class SubA1 {
    public static String static_b="父类静态变量";
    public String b="父类变量";
    static{
        System.out.println(static_b);
        System.out.println("父类静态方法");
    }
    {
        System.out.println("父类普通方法");
        System.out.println(b);
    }
    public SubA1(){
        System.out.println("父类构造方法");
    }
}



public class A1 extends SubA1{

    /**
     * @param args
     */
    public static String static_a="子类静态变量";
    public String a="子类变量";
    static{
        System.out.println(static_a);
        System.out.println("子类静态方法");
    }
    {
        System.out.println("子类普通方法");
        System.out.println(a);
    }
    public A1(){
        System.out.println("子类构造方法");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new A1();

    }

}


直接看输出结果:

父类静态变量
父类静态方法
子类静态变量
子类静态方法
父类普通方法
父类变量
父类构造方法
子类普通方法
子类变量
子类构造方法

可以看出,创建子类对象时,先创建了父类对象,创建父类对象之前,调用了父类静态方法,然后初始化子类,调用了子类静态方法,然后初始化父类普通方法,最后调用父类构造方法产生父类对象,再初始化子类普通方法,最后产生子类对象。