java构造方法
当我们不定义构造方法的时候,如果直接赋值会出现报错:
package com.imooc.constructionmethod; class ExamplePerson { public String name; public int age; } public class example { public static void main(String[] args) { ExamplePerson mi = new ExamplePerson("mi",12); //不能这样直接传参 System.out.println(mi.name); } }
执行结果:
之前我们是这样:
public class example2 { public static void main(String[] args) { ExamplePerson mi = new ExamplePerson(); mi.name = "mi"; //直接给字段赋值 System.out.println(mi.name); } }
当然,还可以配置一个方法:
public void setName(String name) { this.name = name; } public String getName() { return name; }
这样就可以获取值了:
mi.setName("mi");
System.out.println(mi.getName());
但是这样,貌似有些麻烦,下面是python中实例化一个对象的示例:
class Student(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中,也是有构造方法的
package com.imooc.constructionmethod; class ExamplePerson3 { private String name; private int age; public ExamplePerson3(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(String[] args){ ExamplePerson3 mao = new ExamplePerson3("mao",18); System.out.println(mao.getName()); System.out.println(mao.getAge()); } }
这样在创建这个对象的时候,就可以实例化对象的属性,与python创建一个对象类似。
我们可以看到,上面的构造方法与类名一样。与普通函数不同的是,构造方法没有返回值。
需要注意的是,调用构造方法必须使用new操作符。
1.默认构造方法
是不是任何类都有构造方法了?是。
之前很多示例,我们都没有配置构造方法,为啥还是new Person可行的?
package com.imooc.objectoriented; class Person { private String name; private int age; } public class ObjectMethod { public static void main(String[] args) { Person ming = new Person(); ming.name = "mingwang"; ming.age = 26; System.out.println(ming.name); } }
因为如果一个类没有配置构造方法,那么编译器会自动为我们生成一个构造方法,他没有参数,也没有执行语句,就这样:
class Person { .... public Person(){ } }
2.多构造方法
如果既要使用不带参数的构造方法,也想使用带参数的构造方法,那么就必须把两个构造方法都配置出来。
可以给一个类定义多个构造方法,在通过new操作符调用的时候,编译器会通过构造方法的参数数量、位置和类型来选择构造方法。
package com.imooc.constructionmethod; class ExamplePerson3 { private String name = "mao"; private int age = 18; public ExamplePerson3(String name,int age) { this.name = name; this.age = age; } public ExamplePerson3() { this.name = name; this.age = 12; } public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(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的形式。
package com.imooc.constructionmethod; class ExamplePerson3 { private String name = "mao"; private int age = 18; public ExamplePerson3(String name,int age) { this.name = name; this.age = age; } public ExamplePerson3() { this("niao",3); //构造方法还可以调用其他的构造方法,通过this形式 } public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(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.初始化赋值
在一个对象已经构造完成的时候,其属性其实已经填充完毕。
package com.imooc.constructionmethod; class ExamplePerson3 { private String name; //null private int age; //0 public ExamplePerson3() {} public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(String[] args){ ExamplePerson3 ming = new ExamplePerson3(); System.out.println(ming.getName()); //null System.out.println(ming.getAge()); //0 } }
在上述示例中,我们并没有赋值,但是每个属性都已经有值。
属性的默认值是其字段类型的默认值。
当然,还可以在定义属性的时候,直接定义值:
package com.imooc.constructionmethod; class ExamplePerson3 { private String name = "mao"; private int age = 18; public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(String[] args){ ExamplePerson3 ming = new ExamplePerson3(); System.out.println(ming.getName()); //mao System.out.println(ming.getAge()); //18 } }
那么,既对字段进行初始化,又调用了构造函数,字段该如何取值了?
package com.imooc.constructionmethod; class ExamplePerson3 { private String name = "mao"; private int age = 18; public ExamplePerson3(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } public class example3 { public static void main(String[] args){ ExamplePerson3 ming = new ExamplePerson3("ke",27); System.out.println(ming.getName()); //ke System.out.println(ming.getAge()); //27 } }
在Java中创建对象示例的时候,按照如下顺序进行初始化:
(1)先初始化字段,如果没有给值,那么采用默认值。
(2)执行构造方法的代码进行初始化。
因此上方函数会显示构造方法的赋值。