Java构造器

来源:互联网 发布:软件外包介绍网站 编辑:程序博客网 时间:2024/06/07 01:41

构造器定义

      构造器是用来初始化类实例。在对象编程语言中,一般在定义了一个类型之后,为了能使用它,必须把这个类型具体化,也就是指定为一个具体的对象。而构造函数就是从定义出发,建立与定义相对应的对象。用计算机语言来说,光有定义是不能使用,必须通过构造函数来分配内存空间给可使用的对象。

构造器的声明语法

<作用域> <类名> (<参数列表>){        <方法体>}

构造器的使用规则

  • 构造器的名称始终与其类名相同
  • 一个类可以有多个构造器
  • 构造器可以有0、1个或多个参数
  • 构造器始终使用new关键字进行调用
  • 构造器没有返回值

构造方法与成员方法的区别

  • 修饰符不同
    构造方法只能使用public、private、protected访问修饰符,而不能使用static、final、synchronized、abstract等非访问修饰符。这是因为构造方法用于初始化一个实例对象,所以static修饰是没有任何意义的;多个线程不会同时创建内存地址相同的同一个对象,所以synchronized修饰没有意义;构造方法不能被子类继承,所以final和abstract修饰没有意义。
  • 返回值不同
    构造方法没有返回值。
  • 构造方法名与类名相同。

缺省构造器

  • 每个类至少有一个构造器
  • 如果你没有手工编写一个构造器,则系统在编译时自动添加一个缺省构造器
public class A {    public static void main(String[] args) {        A a = new A();//调用系统默认的无参构造器    }}
  • 一旦自己定义了自己的构造函数java就会收回自己的默认构造函数,因此建议自己要书写无参构造函数。
public class A {    public A(String name){        System.out.println(name);    }    public static void main(String[] args) {        //A a = new A();//报错,因为没有相应的无参构造函数的定义        A a2 = new A("a2");//输出结果为:a2    }}

构造器不能被继承

  • 子类继承父类所有的成员方法和成员变量
  • 但子类不继承父类的构造器。

调用其他构造器

  • 调用父类构造器用super()方法
    使用super可以调用父类的构造器
public class A {    public A(){        System.out.println("A--无参构造器");    }    public A(String name){        System.out.println("A--有参构造器:"+name);    }}public class B extends A{    public B(){        super();        System.out.println("B--无参构造器");    }    public B(String name){        super(name);        System.out.println("B--有参构造器:"+name);    }    public static void main(String[] args) {        B b1 = new B();        System.out.println("--------------");        B b2 = new B("b2");    }}//输出结果为:/*A--无参构造器B--无参构造器--------------A--有参构造器:b2B--有参构造器:b2             */

         使用super也可以在成员方法中调用父类的成员方法

public class A {    public void method(){        System.out.println("method:A");    }}public class B extends A{    public void method(){        System.out.println("method:B");        super.method();    }    public static void main(String[] args) {        B b1 = new B();        b1.method();            }}//运行结果为://A--无参构造器//B--无参构造器
  • 调用当前类构造器用this()方法
    this在构造器中可以调用其他的构造器,但必须在第一行且只能调用一次。
public class A {    public A(){        System.out.println("无参构造器");    }    public A(String name){        this();        System.out.println("有参构造器:"+name);    }    public static void main(String[] args) {        A a2 = new A("a2");//有参构造器    }}//运行结果为://无参构造器//有参构造器:a2

         另外,this关键字也代表当前的实例对象,因此this关键字不能用于static方法中。

public void setName(String name) {    this.name = name;}
  • 子类默认调用父类的无参构造器,如果父类自己定义了有参构造器而没有定义无参构造器,那么就会报错。但这时如果子类显示的调用父类的有参构造器,就不会报错。
public class A {    public A(String name){        System.out.println("A--有参构造器:"+name);    }}public class B extends A{    public B(String name){        super(name);        System.out.println("B--有参构造器:"+name);    }    public static void main(String[] args) {        B b2 = new B("b2");    }}//输出结果为://A--有参构造器:b2//B--有参构造器:b2

         从上例也可以看出先初始化父类的构造器,再初始化子类的构造器。

初始化顺序问题

初始化顺序:
1. 静态成员首先被初始化且只初始化一次。
2. 父类构造器被初始化。
3. 实例变量被初始化。
4. 本类构造方法被初始化。

由下述代码可得上述结论

public class A {    public A(){        System.out.println("A--无参构造器");    }    public A(String name){        System.out.println("A--有参构造器:"+name);    }}public class B extends A{    A a2 = new A("a2");    static A a3 = new A();    public B(String name){        super(name);        System.out.println("B--有参构造器:"+name);    }    public static void main(String[] args) {        B b1 = new B("b1");        B b2 = new B("b2");    }}//运行结果为:/**    A--无参构造器    A--有参构造器:b1    A--有参构造器:a2    B--有参构造器:b1    A--有参构造器:b2    A--有参构造器:a2    B--有参构造器:b2*/
0 0