Constructor构造方法

        在我们创建实例时,我们经常需要同时初始化这个实例,例如:

Person ming =new Person();
ming.setName("卫什么");
ming.setAge("18");

          这样需要三行代码,实际上,在我们创建实例时,是通过构造方法来初始化实例的,我们可以自己定义一个构造方法,使在创建Person实例时,一次性传入name和age,完成初始化:

public class Main{    
    public static void main(String[] args){
        Person p=new Person("卫什么",18);
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}
class Person{
    private String name;
    private int age;
    //构造方法
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
}

构造方法相比其他方法比较特殊,表现在以下几个方面:

①构造方法的方法名必须和类名相同,但是参数没有限制,可以没有也可以有

②构造方法没有返回值,也不需要void

调用构造方法,必须使用new 关键字

④在类中如果没有定义构造方法,会存一个默认无参的构造方法

默认的构造方法

        任何类都有构造方法,在上一篇文章中,我们并没有为Person类编写构造方法,那为什么我们依然可以调用new Person()呢?是因为如果在一个类中没有定义构造方法,那么编译器会自动生成一个默认的构造方法,他没有参数,也没有执行语句,类似于这样:

class Person{
    public Person(){
    }
}

        当我们自定义了一个构造方法后,编译器就不会在生成默认的无参构造方法,例如:

public class Main{    
    public static void main(String[] args){
        Person p=new Person();//编译错误
    }
}
class Person{
    private String name;
    private int age;
    //构造方法
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
}

此时会发生编译错误,因为没有Person()这个构造方法。

多个构造方法

在一个类中,可以定义多个构造方法,在通过new关键字调用时,编译器会自动通过构造方法的:参数数量、类型、顺序来匹配不同的构造方法,例如:

public class Order_test{
    public static void main(String [] args){
        //创建一个订单对象
        //通过无参构造方法创建
        Order o1=new Order();
        o1.setPay(187.9);//保存金额

        //通过有参构造方法创建
        Order o2=new Order(157.92);
        
        //打印订单
		System.out.println("订单1:"+o1);
		System.out.println("订单2:"+o2);
    }
class Order {
    //成员变量
    private String orderNo;
    private double pay;
    //无参构造方法
    public Order(){
        //获取当前日期
        String now=LocalDateTime.now().format(DateTimeFormatter
                    .ofPattern("yyyyMMddHHmmss"));
        //流水号
        String trace=UUID.randmUUID().toString.subtring(0,5);
        //订单编号
		this.orderNo=now+trace;
    }
    //有参构造方法
    public Order(double pay){
        //调用无参构造方法,自动生成订单编号
        //构造方法的调用应当是当前构造方法的第一句
        this();
        //存入金额
        this.pay=pay;
    }
    //set和get方法
	public void setordreNo(String ordreNo) {
		this.orderNo=ordreNo;
	}
	public String getordreNo() {
		return orderNo;
	}
	public double getPay() {
		return pay;
	}
	public void setPay(double pay) {
		this.pay = pay;
	}

}

此时,运行出的结果为:

         为什么打印出的是订单的地址呢?因为Order对象是我们自己创建的,它没有自己的toString()方法,所以会默认使用父类Object的toString方法,如下:

 所以我们要自己重写toString()方法,使其按照我们想输出的格式输出:

public class Order_test{
    public static void main(String [] args){
        //创建一个订单对象
        //通过无参构造方法创建
        Order o1=new Order();
        o1.setPay(187.9);//保存金额

        //通过有参构造方法创建
        Order o2=new Order(157.92);
        
        //打印订单
		System.out.println("订单1:"+o1);
		System.out.println("订单2:"+o2);
    }
class Order {
    //成员变量
    private String orderNo;
    private double pay;
    //无参构造方法
    public Order(){
        //获取当前日期
        String now=LocalDateTime.now().format(DateTimeFormatter
                    .ofPattern("yyyyMMddHHmmss"));
        //流水号
        String trace=UUID.randmUUID().toString.subtring(0,5);
        //订单编号
		this.orderNo=now+trace;
    }
    //有参构造方法
    public Order(double pay){
        //调用无参构造方法,自动生成订单编号
        //构造方法的调用应当是当前构造方法的第一句
        this();
        //存入金额
        this.pay=pay;
    }
    //toString()方法
    public String toString(){
        return String.format("订单编号:%s,订单金额:%f",
                            this.getOrderNo(),this.getPay());
    //set和get方法
	public void setordreNo(String ordreNo) {
		this.orderNo=ordreNo;
	}
	public String getordreNo() {
		return orderNo;
	}
	public double getPay() {
		return pay;
	}
	public void setPay(double pay) {
		this.pay = pay;
	}

}

输出结果:

 构造代码块

语法特征:在每个构造方法执行前,自动调用,每次创建对象都会调用构造代码块一次,但是优先于构造方法,但是,如果不实例化对象,构造代码块是不会执行的,例如:

public class Employee_text{
    public static void main(String[] args){
        //调用无参的构造方法   
        Employee emp1=new Employee ();
        System.out.println(emp1); 
    }
 }
class Employee{
    //成员变量(按照数据类型自动初始化)
    private String name;//null
	private String job;//null
	private double salary;//0.0
	private  int level;//0
    //构造代码块
    {
        this.name="匿名";
        this.job="暂未分配岗位";
        this.salary=0.1;
		this.level=1;  
    }  
    //构造方法(无参)
    public Employee(){
		
    }
    public String toString() {
		return String.format("姓名:%s,岗位:%s,薪资:%f,等级:%d"                            
             ,this.getName(),this.getJob(),this.getSalary()
             ,this.getLevel());
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	

        此时,无参构造方法中并未有任何语句,但是,构造代码块会在调用构造方法时在构造方法前执行,所以输出为:

当构造方法为有参构造方法时,传入的数据会将构造代码块中的数据覆盖:

public class Employee_text{
    public static void main(String[] args){
        //调用无参的构造方法   
        Employee emp1=new Employee ();
        System.out.println(emp1); 
		//调用有参的构造方法
	    Employee emp3=new Employee("jack");
		System.out.println(emp3);

		Employee emp2=new Employee("小佳","女明星",100000,10);
		System.out.println(emp2);
    }
 }
class Employee{
    //成员变量(按照数据类型自动初始化)
    private String name;//null
	private String job;//null
	private double salary;//0.0
	private  int level;//0
    //构造代码块
    {
        this.name="匿名";
        this.job="暂未分配岗位";
        this.salary=0.1;
		this.level=1;  
    }  
    //构造方法(无参)
    public Employee(){
		
    }
    //有参构造方法1
    public Employee(String name) {
        this.name=name;
    }
    public String toString() {
		return String.format("姓名:%s,岗位:%s,薪资:%f,等级:%d"                            
             ,this.getName(),this.getJob(),this.getSalary()
             ,this.getLevel());
	}
    //有参构造方法2
    public Employee(String name,String job,double salary,int level) {
		this.name=name;
		this.job=job;
		this.salary=salary;
		this.level=level;
    }        
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	

输出结果为:

姓名:匿名,岗位:暂未分配岗位,薪资:0.100000,等级:1
姓名:jack,岗位:暂未分配岗位,薪资:0.100000,等级:1
姓名:小佳,岗位:女明星,薪资:100000.000000,等级:10

注意:如果存在多个构造代码块,则按照书写顺序执行


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值