Java入门-------构造方法和构造方法的重载
构造方法:
当我们实例化一个对象之后,如果要为这个对象中的属性赋值,则必须通过直接访问对象的属性或调用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类对象,都会在执行构造方法之前执行构造代码块。