今天看到设计模式中的桥梁模式,有地方不理解,原来是构造函数的问题,下面将构造函数的使用写明。
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();
}
}
直接看输出结果:
父类静态变量
父类静态方法
子类静态变量
子类静态方法
父类普通方法
父类变量
父类构造方法
子类普通方法
子类变量
子类构造方法
可以看出,创建子类对象时,先创建了父类对象,创建父类对象之前,调用了父类静态方法,然后初始化子类,调用了子类静态方法,然后初始化父类普通方法,最后调用父类构造方法产生父类对象,再初始化子类普通方法,最后产生子类对象。