Java提供了多种编写构造器的机制,Java中的构造器有以下特点:
- 用来描述对象的创建过程
- 构造器声明在类的内部
- 构造方法的方法名与类名一致
- 构造方法不能声明返回值类型
- 构造方法可以包含参数,参数一般是创建对象实例的前提条件。
- 重载
重载定义:函数或方法有相同的名称,但是参数列表不同的情形,这样同名不同参数之间的函数或方法相互称为重载函数或重载方法。编译器通过各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配挑选出相应的方法。
Java运行重载任何方法,返回类型不是方法签名(指出方法名和参数类型)的一部分,并且不能有两个名字相同,参数类型相同而返回类型不同的方法。
重载解析:不存在匹配或者没有一个比其他的更好,使得编译器找不到匹配的参数,就会产生编译时错误。
2.默认域初始化
构造器中没有显式地给域赋值,就会被自动地赋予默认值:数值型=0,布尔型=false,对象引用=null;
3.无参数的构造器
如果在编写一个类时没有编写构造器,Javac会自动提供一个无参构造器,该无参构造器将所有的实例设置为默认值,实例域中的数值型数据设置为0,布尔型数据设置为false,所有对象变量设置为null.
public class StudentDemo
{
public staatic void main(String[] args){
Student name=new Student();
}
}
class Student{
/*默认构造器:public Student(){
name=" ";
*/
}
}
如果提供构造器声明,Javac将不再提供默认的构造参数。此时调用默认无参构造器会出错,而调用自定义有参构造器则没问题
public class StudentDemo
{
public static void main(String[] args){
Student name=new Student();//调用默认构造器
Study s=new Study("baba");//调用构造器Study(String n)
}
}
class Student{
/*默认构造器:public Student(){
name=" ";}
*/
}
class Study{
String n;
public Study(String n);
this.name=name;
4.显式域初始化块
在·类定义中,直接将一个初始值(不一定是常量值)赋给任何域
如
class Employee
{
private String name=" ";
}
在执行构造器前先进行赋值操作,最好将一个类的所有构造器中把相同值都赋予某一特定的实例域
如下例通过调用方法对域进行初始化
class Employee
{
private static int nextId;
private int id=assignId();
private static int assignId();
{
int r=nextId;
nextId++;
return r;
}
5.参数名
5.1.自定义字符来命名参数
//用单个字符命名参数
public Employee(String n,double s)
{
name=n;
salary=s;
}
//或者再每个参数前加一个前缀或者后缀
public Employee(String aname,double asalary)
{
name=aname;
salary=asalary;
}
5.2.用this关键字调用本类构造器
参数变量使用相同的名称将实例域屏蔽起来,如果将参数名命名为实例变量名,将引用的是该参数而不是实例域。
可以用this.实例变量 this是隐式参数,代表当前所构造的对象,this必须写在构造器的第一行
public Employee(String name,double salary)
{
this.name=name;
this.salary=salary;
}
5.3this 关键字
可以使用this明确访问当前对象属性,方法和构造方法
public class Student{
String name;
int id;
public Student(String name,int id)
{
this.name=name;
this.id=id;
}
}
如果构造器的第一个语句句型为this(...),这个构造器将调用同类的另一个构造器,
如
publicc Employee(double s)
{
//调用Employee(String,double)
this("Employee"+nextId,s);
nextId;
}
//当调用new Employee(XX)时,Employee构造器将调用EmpLoyee(String,double)构造器
6.初始化块
1一个类声明可以有多个代码块,只要构造类的对象,这些块就会被执行,通常建议将初始化块放在域定义后。
class Student
{
private static int nextId;
private int id;
private String name;
//初始化块
{
id=nextId;
nextId++;
}
public Student(String name)
{
this.name=name;
}
public Employee()
{
name=" ";
}
对静态域进行初始化(有两种机制)
第一种机制:提供一个初始值
//在域定义中,直接给静态域赋予初始值
private static int nextId=1;
第二种机制:使用静态初始化块对静态域进行初始化,格式为:static{代码块}
//静态初始化块
static
{
Random generator=new Random();
nextId=generator.nextInt(1000);
}
Random();//构造一个新的随机生成器
int nextInt(int n);//返回一个0~n-1的随机数
此时需要导入 java.util包中的类接口,提供Random()类随机数,故在文件开头处添加import java.util.*;
总结:
构造器的执行步骤:
- 若不是显式设置成其他值,则所有的数据初始化为默认值(数值型=0,布尔型=false,对象型=null)
- 按照类声明中的次序,依次执行所有域初始化语句和初始化块
- 如果构造器的第一行调用了第二个构造器,则执行第二个构造器的主体
- 执行该构造器的主体
本篇主要叙述了JAVA中类声明的几个特性:
- 重载构造器
- 无参构造器
- 用this(...)调用另一个构造器
- 初始化块:对象初始化块,静态初始化块,实例域初始化块
package ClassesAndProjects;
import java.util.*;
/*
* test constructor and initialization block
* @son.2019-7-28
*/
public class ConstructorTest {
public static void main(String[] args) {
//构造一个employee数组,分别填入三个雇员对象
Worker[] staff=new Worker[3];
staff[0]=new Worker("小芳",7900);
staff[1]=new Worker(7800);
staff[2]=new Worker();
for(Worker e:staff)
System.out.println("name="+e.getName()+",id="+e.getId()+"salary="+e.getSalary());//print out information about all Employee objects
}
}
class Worker
{
private static int nextId;
private int id;
private String name="";//显式域初始化,设置类的实例域的初始状态
private double salary;
//静态初始化块,将nextId设置成0~999的随机值
static
{
Random generator=new Random();
nextId=generator.nextInt(1000);
}
//对象初始化块
{
id=nextId;
nextId++;
}
//重载构造器
//构造器1;参数用单个字符命名
public Worker(String n, double s)
{
name=n;
salary=s;
}
//使用this(...)调用另一个构造器,调用的是public Worker(String n, double s)
public Worker(double s)
{
this("EmployeeIs"+nextId,s);
}
//默认构造器
public Worker()
{
//name=" ";
//salary=0;
//id=nextId,对象初始化中已被初始化
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public int getId() {
return id;
}
}
运行结果