构造方法:
当我们实例化一个对象之后,如果要为这个对象中的属性赋值,则必须通过直接访问对象的属性或调用setter方法才可以,如果需要在实例化对象时,为这个对象的属性赋值,可以通过构造方法实现。
构造方法(也被称为构造器)是类的一个特殊成员方法,在类实例化对象时自动调用。
定义构造方法:
构造方法是一个特殊的成员方法,在定义时,有以下几点需要注意:
<1>构造方法的名称必须与类一致
<2>构造方法名称前不能有任何返回值类型的声明。
<3>不能在构造方法中使用return返回一个值,但是可以单独写return语句作为方法的结束。
举例:
无参构造方法:
public class Example{ public static void main(String[]args){ System.out.println("声明对象...."); student1 stu=null; System.out.println("实例化对象...."); stu=new student1(); } }
class student1{ public student1(){ System.out.println("调用了无参构造方法"); } }
输出:
声明对象.... 实例化对象.... 调用了无参构造方法
含参构造方法:
举例:
public class Example{ public static void main(String[]args){ student1 stu=new student1("张三",19);//注意不要忘记传递参数 stu.read();//调用方法 } }
class student1{ //私有属性-----name和age private String name; private int age; public student1(String n,int a) { name=n; age=a; } public void read(){ System.out.println("我是:"+name+",年龄:"+age); } }
输出:
我是:张三,年龄:19
构造方法的重载:
和普通方法相同,构造方法也可以重载,在一个类中定义多个构造方法,只要每个构造方法的参数或参数个数个数不同即可。
在创建对象时,可以通过调用不同的构造方法为不同的属性赋值。
举例:
class student1{ private String name; private int age; public student1(){} public student1(String n){//构造含1个参数方法 name =n; } public student1(String n,int a){//构造含2个参数方法 name=n; age=a; } public void read() { System.out.println("我是:"+name+",年龄:"+age); } }
public class Example{ public static void main(String[]args){ //通过传递不同个数的参数来调用不同的构造方法 student1 stu1=new student1("张三"); student1 stu2=new student1("李四",30); stu1.read(); stu2.read(); } }
输出:
我是:张三,年龄:0 我是:李四,年龄:30
this关键字:
在Java中,当成员变量与局部变量发生重名问题时,需要使用到this关键字分辨成员变量与局部变量。
Java中的this关键字语法比较灵活,其主要作用有以下几点:
<1>使用this关键字调用本类中的属性。
<2>this关键字调用成员变量.
<3>使用this关键字调用本类的构造方法。
在类的构造方法中,如果参数名称与类属性名称相同,则会导致成员变量和局部变量的名称冲突。
使用this关键字调用本类中的属性:
举例:
public class Example{ public static void main(String[]args){ student1 stu=new student1("张三",19); System.out.println(stu.read()); } }
class student1{ private String name; private int age; public student1(String name,int age){ //类属性名称和参数名称相同 name=name; age=age; } public String read(){ return "我是:"+name+"年龄:"+age; } }
输出:
我是:null年龄:0
从输出结果,我们不难看出,构造方法中的赋值并没有运行成功,这是因为参数名称与对象成员变量名称相同,编译器无法确定那个名称是当前对象的属性,因此当我们赋值名字为张三,年龄为19时,最终并未赋值成功。
为了解决这个问题,Java提供了关键字this指代当前的对象,通过this可以访问当前对象的成员。
将代码修改:
this.name=name; this.age=age;
输出:
我是:张三年龄:19
使用this关键字调用成员方法:
class student1{ public static void main(String[] args){ } public void openMouth(){ } public void read(){ this.openMouth();//通过关键字调用成员方法 } }
使用this关键字调用构造方法:
构造方法是在实例化对象时被Java虚拟机自动调用,在程序中不能像调用其他成员方法一样调用构造方法,但可以在一个构造方法中使用“this(参数一,参数二…)”的形式调用其他的构造方法。
举例:
class student1{ private String name; private int age; public student1(){ System.out.println("实例化了一个新的student对象:"); } public student1(String name,int age){ this();//调用无参的构造方法 this.name=name; this.age=age; } public String read(){ return "我是:"+name+",年龄:"+age; } }
public class Example{ public static void main(String[]args){ student1 stu=new student1("张三",19); System.out.println(stu.read()); } }
输出:
实例化了一个新的student对象: 我是:张三,年龄:19
在使用this调用类的构造方法时,应注意以下几点:
<1>只能在构造方法中使用this调用其他的构造方法,不能在成员方法中通过this调用其他构造方法。
<2>在构造方法中,使用this调用构造方法的语句必须位于第一行,且只能出现一次。
举例:
class student1 { private String name; private int age; public student1() { System.out.println("实例化了一个新的student对象:"); } public student1(String name, int age) { this(); this.name = name; this.age = age; } public String read() { return "我是:" + name + ",年龄:" + age; } public student1(String name) { System.out.println("有参的构造方法被调用了"); this(age); } }
编译未通过,报错如下:
<3>不能在一个类的两个构造方法中使用this互相调用
举例:
class student1{ public static void main(String[] args){ } public student1(){ this("张三"); System.out.println("无参的构造方法被调用了"); } public student1 (String name){ this(); System.out.println("有参的构造方法被调用了"); } }
编译未通过,报错如下:
代码块:
代码块,简单来说,就是用“{}”括起来的一段代码,根据位置及声明关键字的不同,代码块可以分为4种:普通代码块,构造块,静态代码块,同步代码块。
普通代码块:
普通代码块就是直接在方法或语句中定义的代码块。
举例:
//虽然定义了两个变量名相同的变量,但是由于代码块将变量的作用域分割开了,所以并不影响使用这两个变量名相同的变量 public class student1 { public static void main(String[] args) { { int age = 18; System.out.println("这是普通代码块,age:" + age); } int age = 30; System.out.println("age:" + age); } }
输出:
这是普通代码块,age:18 age:30
构造块:
构造代码块是直接在类中定义的代码块。
举例:
class student1{ String name; public student1(){ System.out.println("我是student类的构造方法"); } //直接定义在类中的代码块为构造代码块 {//定义在成员位置----与构造方法,成员属性同级 System.out.println("我是构造代码块"); } }
public class Example{ public static void main(String[]args){ student1 stu1=new student1(); student1 stu2=new student1(); } }
输出:
我是构造代码块 我是student类的构造方法 我是构造代码块 我是student类的构造方法
通过输出结果,我们可以得出如下结论:
<1>在实例化student1类对象stu1,stu2时,构造块的执行顺序大于构造方法(这里和构造块写在前面还是后面无关)。例如上述实例,我们就将其写在了后面。
<2>每当实例化一个student1类对象,都会在执行构造方法之前执行构造代码块。