当我们不定义构造方法的时候,如果直接赋值会出现报错:
packagecom.imooc.constructionmethod;classExamplePerson {publicString name;public intage;
}public classexample {public static voidmain(String[] args) {
ExamplePerson mi= new ExamplePerson("mi",12); //不能这样直接传参
System.out.println(mi.name);
}
}
执行结果:
之前我们是这样:
public classexample2 {public static voidmain(String[] args) {
ExamplePerson mi= newExamplePerson();
mi.name= "mi"; //直接给字段赋值
System.out.println(mi.name);
}
}
当然,还可以配置一个方法:
public voidsetName(String name) {this.name =name;
}publicString getName() {returnname;
}
这样就可以获取值了:
mi.setName("mi");
System.out.println(mi.getName());
但是这样,貌似有些麻烦,下面是python中实例化一个对象的示例:
classStudent(object):
def __init__(self,name,score):
self.name=name
self.score=score
def print_score(self):
print('%:%s'%(self.name,self.score))
然后示例化就是如下方式:
bart = Student('Bart Simpson',59)
lisa= Student('Lisa Simpson',87)
其实python之所以可以这样,就是因为__init__是构造函数。其实在java中,也是有构造方法的
packagecom.imooc.constructionmethod;classExamplePerson3 {privateString name;private intage;public ExamplePerson3(String name,intage) {this.name =name;this.age =age;
}publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 mao= new ExamplePerson3("mao",18);
System.out.println(mao.getName());
System.out.println(mao.getAge());
}
}
这样在创建这个对象的时候,就可以实例化对象的属性,与python创建一个对象类似。
我们可以看到,上面的构造方法与类名一样。与普通函数不同的是,构造方法没有返回值。
需要注意的是,调用构造方法必须使用new操作符。
1.默认构造方法
是不是任何类都有构造方法了?是。
之前很多示例,我们都没有配置构造方法,为啥还是new Person可行的?
packagecom.imooc.objectoriented;classPerson {privateString name;private intage;
}public classObjectMethod {public static voidmain(String[] args) {
Person ming= newPerson();
ming.name= "mingwang";
ming.age= 26;
System.out.println(ming.name);
}
}
因为如果一个类没有配置构造方法,那么编译器会自动为我们生成一个构造方法,他没有参数,也没有执行语句,就这样:
classPerson {
....publicPerson(){
}
}
2.多构造方法
如果既要使用不带参数的构造方法,也想使用带参数的构造方法,那么就必须把两个构造方法都配置出来。
可以给一个类定义多个构造方法,在通过new操作符调用的时候,编译器会通过构造方法的参数数量、位置和类型来选择构造方法。
packagecom.imooc.constructionmethod;classExamplePerson3 {private String name = "mao";private int age = 18;public ExamplePerson3(String name,intage) {this.name =name;this.age =age;
}publicExamplePerson3() {this.name =name;this.age = 12;
}publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 ming= new ExamplePerson3("ke",27);
System.out.println(ming.getName());//ke
System.out.println(ming.getAge()); //27
ExamplePerson3 king = new ExamplePerson3("king"); //编译器会根据参数个数来选择构造方法
System.out.println(king.getName()); //king
System.out.println(king.getAge()); //12
}
}
构造方法还可以调用其他的构造方法,以此来提高代码的复用,通过this的形式。
packagecom.imooc.constructionmethod;classExamplePerson3 {private String name = "mao";private int age = 18;public ExamplePerson3(String name,intage) {this.name =name;this.age =age;
}publicExamplePerson3() {this("niao",3); //构造方法还可以调用其他的构造方法,通过this形式
}publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 ming= new ExamplePerson3("ke",27);
System.out.println(ming.getName());//ke
System.out.println(ming.getAge()); //27
ExamplePerson3 king = new ExamplePerson3(); // System.out.println(king.getName()); //niao
System.out.println(king.getAge()); //3
}
}
3.初始化赋值
在一个对象已经构造完成的时候,其属性其实已经填充完毕。
packagecom.imooc.constructionmethod;classExamplePerson3 {private String name; //null
private int age; //0
publicExamplePerson3() {}publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 ming= newExamplePerson3();
System.out.println(ming.getName());//null
System.out.println(ming.getAge()); //0
}
}
在上述示例中,我们并没有赋值,但是每个属性都已经有值。
属性的默认值是其字段类型的默认值。
当然,还可以在定义属性的时候,直接定义值:
packagecom.imooc.constructionmethod;classExamplePerson3 {private String name = "mao";private int age = 18;publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 ming= newExamplePerson3();
System.out.println(ming.getName());//mao
System.out.println(ming.getAge()); //18
}
}
那么,既对字段进行初始化,又调用了构造函数,字段该如何取值了?
packagecom.imooc.constructionmethod;classExamplePerson3 {private String name = "mao";private int age = 18;public ExamplePerson3(String name,intage) {this.name =name;this.age =age;
}publicString getName() {returnname;
}public intgetAge() {returnage;
}
}public classexample3 {public static voidmain(String[] args){
ExamplePerson3 ming= new ExamplePerson3("ke",27);
System.out.println(ming.getName());//ke
System.out.println(ming.getAge()); //27
}
}
在Java中创建对象示例的时候,按照如下顺序进行初始化:
(1)先初始化字段,如果没有给值,那么采用默认值。
(2)执行构造方法的代码进行初始化。
因此上方函数会显示构造方法的赋值。