java---构造方法(第三课时)

第三课时   构造方法的总结

 

知识回顾:类的组成:1) 属性:根据对象的特征定义

                    2) 方法:用于实例化对象,实现对象的行为

                               I. 普通方法:                     

                               II. 构造方法:

纲要:1.构造方法

          2.方法重载

          3.this关键字

          4.值传递

          5.引用传递

 

一.构造方法:普通方法和构造方法的区别

1.格式:

1.1普通方法:

   访问限定符 返回值类型 方法名(数据类型  参数名1,数据类型 参数名2... ]{

                  //方法体

     }

例: //为学生类定义一个设置名字的方法

     public void setName(String  n){

              name=n;

     }

1.2构造方法:

  访问限定符  类名数据类型  参数名1,数据类型 参数名2... ]{

              //方法体

  }

例: //为学生类定义一个不带参数的构造函数

     public Student(){

 

  }

2.格式的异同:

2.1格式的相同点:I . 都有访问限定符,可以是公有(public)可以是私有(private)也可以

                   是受保护的(protected)。

              II . 参数可以带也可以不带,也可以带多个参数也可以不带参数,多个参

                   数时必须用逗号隔开,所带参数必须有相应的数据类型和参数名。

             III . 都带有各自的方法体。

2.2格式的不同点:I . 普通方式必须有返回值类型,如果没有返回值,则写void

                 构造方法没有返回值类型。

              II. 普通方法的方法名可以根据行为的名字进行命名,

               构造方法的方法名必须与类名一致

3.用途不同

3.1普通方法:根据对象的行为定义,用于实现对象的行为。

3.2构造方法:I . 实例化对象 (见如下例题)

          II. 初始化对象  (详情见方法重载部分)

          III. 返回开辟的内存空间的首地址 (详情见引用传递部分,已用红色标注)

4.例题:

public class student {

	private String name;  //学生的名字属性
	private int score=0;  //学生的学分属性,初始值为0

	/**
     * 设置学生名字的方法
     * @param n 学生的名字参数
	 */
	public void setName(String n){
		name=n;
	}   

	/**
	 * 获取学生名字的方法
	 * @return  学生的名字
	 */
	public String getName(){
		return name;
	}

	//程序主函数入口
	public static void main(String [] args){

		//使用默认的构造函数实例化一个student类对象
		student stu=new student();
		
		//调用普通方法为对象设置名字
		stu.setName("小明");
        
        //调用普通方法将获取的名字赋值给一个变量
		String stuName=stu.getName();
		
		//输出该名字
		System.out.println(stuName);
	}
}    

 

.方法重载:包括构造方法的重载和普通方法的重载

1.什么情况下使用方法重载?

  在同一个类中,不同的数据类型使用相同的方法时可以使用重载。

1.1构造方法重载:实例化对象的时候,有些对象需要参数,有些对象不要参数。

               (通俗来讲就是对象一“出生”的时候,就具备有不同的东西)

               例如:对于一个汽车类,制造一个汽车的时候,

                     可能有些汽车自带了导航系统(带导航参数),

                     而有些汽车却没有(不带导航参数),

                     那么在生产的过程中两者就需要用到不同的制造工具。

1.2普通方法重载:相同的方法可以用不同的“道具”来实现。

                例如:求一个三角形的面积,

                      可以通过 底*/2来实现(那么就需要底和高两个参数),

                      也可通过三边的长求解(那么就需要三个边长参数),

                      还可以通过两边的长和夹角来求解(那么就需要两个边长参数和 

                      一个夹角参数)。

2.实现方法重载的条件?

(1)方法名相同

(2)参数不同(参数的类型,参数的个数只要一个不同即可)

(注: 方法体、访问限定符和返回值类型可以不同)

 

3.重载后的方法如何使用?

 重载后的方法与没重载的方法使用格式一样,都是 对象名.方法名([参数]);

 对象会根据参数的类型和参数的个数搜寻相匹配的方法,进行调用。

 

4.例题:

 

 

public class student {

	private String name;  //学生的名字属性
	private int score=0;  //学生的学分属性,初始值为0

	/**
	 * 定义一个不带参数的构造函数
	 */
	public student(){
		
	}
	
	/**
     *重载一个带参数的构造函数
     * @param name 学生的名字参数
     */
	public student(String n){
		name=n;
	}
	
	/**
     * 设置学生名字的方法
     * @param n 学生的名字参数
	 */
	public void setName(String n){
		name=n;
	}   

	/**
	 * 获取学生名字的方法
	 * @return  学生的名字
	 */
	public String getName(){
		return name;
	}
	
	/**
	 * 学生学习的方法,不带参数
	 */
	public void study(){
		score++;
		System.out.println(name+"学习了,学分加1!");
	}

	public void study(int hour){
		score+=hour;
		System.out.println(name+"学习了"+hour+"小时,学分加"+hour);
	}
	
	//程序主函数入口
	public static void main(String [] args){

		//用无参的构造函数实例化一个student类对象
		student stu1=new student();
		
		//使用带参数的构造函数实例化一个student类对象,并初始化学生的姓名属性
		student stu2=new student("小红");
		
		//stu1对象调用普通方法为对象设置名字
		stu1.setName("小明");
        
		//stu1对象调用不带参数的study方法
		stu1.study();
		
		//stu2对象调用带参数的study方法
		stu2.study(5);
	}
}       

 

 

 

 

 

.关键字this:表示当前对象

1.用于解决参数与属性同名时引起的问题

例:

private String name;  //学生的名字属性	
    /**
	 * 设置学生名字的方法
	 * @param n 学生的名字参数
	 */
	public void setName(String name){
		name=name;
	}   

 

我们的目的是:将setName的参数值name(左边的name)赋给当前对象的name属性

             (右边的name)。

        但是:当参数名和属性名同,由于java的就近原则,和name属性相比,右边的

              name和参数名name较近,因此,Java会自动将其识别为参数name而非属

              性name

        所以:上述方方法体只是执行了,将参数name的值传给参数name,而无法实

              现我们的最终目的。

        因此:我们可以引入this关键字。如下代码:

private String name;  //学生的名字属性	
    /**
	 * 设置学生名字的方法
	 * @param n 学生的名字参数
	 */
	public void setName(String name){
		this.name=name;
	}   

 

 

 

引入this关键字的作用:使用了this关键字后this.name就表示该对象的name属性,

 

                      这样就可以实现给名字属性的赋值。

 

 

 

2.调用当前类的构造函数

 

例:

 

	/**
	 * 定义一个不带参数的构造函数
	 */
	public student(){
		//调用带参数的构造函数
		this("小黑");
	}
	
	/**
     * 重载一个带参数的构造函数
     * @param name 学生的名字参数
     */
	public student(String n){
		name=n;
	}

 

 

 

 

 

在构造函数中,通过this指针可以调用非本身的构造函数(构造函数不能调用自身,否则会无限的递归下去)

 

格式:this[参数1,参数2...]

 

 

 

3.例题:1)没用this关键字前

public class student {

	private String name;  //学生的名字属性	

	/**
     *定义一个带参数的构造函数
     * @param name 学生的名字参数
     */
	public student(String name){
		name=name;
	}
	
	/**
     * 设置学生名字的方法
     * @param n 学生的名字参数
	 */
	public void setName(String n){
		name=n;
	}   

	/**
	 * 获取学生名字的方法
	 * @return  学生的名字
	 */
	public String getName(){
		return name;
	}

	//程序主函数入口
	public static void main(String [] args){

		//使用带参数的构造函数实例化一个student类对象
		student stu=new student("小红");

		//获取stu对象的名字
		String b=stu.getName();		
		
		//输出名字
		System.out.println("stu对象的名字为:"+b);				

	}
}    

 

 

 

结果为:

 

 

 

     stu对象的名字为:null

 

2)使用this关键字后

 

public class student {

	private String name;  //学生的名字属性	

	/**
     *定义一个带参数的构造函数
     * @param name 学生的名字参数
     */
	public student(String name){
		this.name=name;
	}
	
	/**
     * 设置学生名字的方法
     * @param n 学生的名字参数
	 */
	public void setName(String n){
		name=n;
	}   

	/**
	 * 获取学生名字的方法
	 * @return  学生的名字
	 */
	public String getName(){
		return name;
	}

	//程序主函数入口
	public static void main(String [] args){

		//使用带参数的构造函数实例化一个student类对象
		student stu=new student("小红");

		//获取stu对象的名字
		String b=stu.getName();		
		
		//输出名字
		System.out.println("stu对象的名字为:"+b);				

	}
}       

 

 

 

结果为:

 

 

 

       stu对象的名字为:小红

 

.值传递

 

1.适用于什么数据类型?

 

适用于基本数据类型(8种):字节型(byte)、字符型(char)、短整型(short)、整型(int

 

                          长整形(long)、浮点型(float)、双精度(double)、

 

                          布尔型(booolean

 

2.传递内容和如何传递?    

 

传递内容:数值。

 

如何传递如下:已知学生类的学习方法

 

	public void study(int hour){
		//学分的初始值为0,学习了几小时就加多少学分
		score+=hour;
		//输出
		System.out.println(name+"学习了"+hour+"小时,学分加"+hour);
	}

 

 (1)定义一个整型变量 int i=5

 
java---构造方法(第三课时)
 

(2)对象stu调用学习方法:stu.study(i)

 

第一步:将int 的值:传给参数hour,此时内存如下 
java---构造方法(第三课时)
 

第二步:执行分数加hour的操作后,分数变为5


java---构造方法(第三课时)
 

第三步:分数改变后,为分数属性临时创建的score空间中的内容会被javagc销毁,同时会释放该内存空间。内存中的内容改变如下:


java---构造方法(第三课时)
 

 

.引用传递

 

1.适用于什么数据类型?

 

适用于复杂数据类型(引用数据类型、对象数据类型、类类型、自定义类型)

 

classinterfaceabstract class和数组都属于该类型

 

2.传递内容和如何传递?

 

传递内容:地址。

 

如何传递如下:已知student类的构造函数如下

 

	/**
	 * 定义一个不带参数的构造函数
	 */
	public student(){
		
	}
	
	/**
     * 重载一个带参数的构造寒素
     * @param name 学生的名字参数
     */
	public student(String n){
		name=n;
	}

 

 

 

(1)实例化一个student对象类 :student stu1=new student(“张三”)

 在栈内为stu1开辟一段内存空间,同时为该类的属性和方法在堆中开辟一段内存空间,假设属性和方法对应空间的首地址为123,则将123传给栈中的stu1存储起来,stu1中的内容为在堆中开辟的内存空间的首地址


java---构造方法(第三课时)

(2)用同样的方法实例化另一个对象:student stu2=new student()


java---构造方法(第三课时)
 

(3)引用传递,stu1中的内容123(首地址)赋值给stu2stu2=stu1,赋值完后stu2在堆中开辟的内存内容会被gc销毁,同时释放掉该内存空间。

 
java---构造方法(第三课时)
 

此时,如果对stu2执行setName操作,由于stu1stu2中的内容都是123,所以不仅stu2中的内容发生改变,stu1的内容也会随之改变。

 

 

 

3.例题:代码如下:

 

public class student {

	private String name;  //学生的名字属性	

	/**
     * 定义一个带参数的构造寒素
     * @param name 学生的名字参数
     */
	public student(String name){
		this.name=name;
	}
	
    /**
	 * 设置学生名字的方法
	 * @param n 学生的名字参数
	 */
	public void setName(String name){
		this.name=name;
	}
	
	/**
	 * 获取学生名字的方法
	 * @return  学生的名字
	 */
	public String getName(){
		return name;
	}
	
	//程序主函数入口
	public static void main(String [] args){

		//使用带参数的构造函数实例化两个student类对象
		student stu1=new student("张三");
		student stu2=new student("李四");

		System.out.println("改变stu2对象的名字前:");		
		//获取stu1对象的名字
		String a=stu1.getName();		
		//输出名字
		System.out.println("stu1对象的名字为:"+a);
		
		//获取stu2对象的名字
		String b=stu2.getName();		
		//输出名字
		System.out.println("stu2对象的名字为:"+b);				
		//引用传递
		stu2=stu1;
		
		//改变stu2对象的名字
		stu2.setName("王五");
		
		System.out.println("改变stu2对象的名字后:");
		
		//获取stu1对象的名字
		a=stu1.getName();		
		//输出名字
		System.out.println("stu1对象的名字为:"+a);
		
		//获取stu2对象的名字
		b=stu2.getName();		
		//输出名字
		System.out.println("stu2对象的名字为:"+b);		
	}
}       

 

 结果为:

 

改变stu2对象的名字前:
stu1对象的名字为:张三
stu2对象的名字为:李四
改变stu2对象的名字后:
stu1对象的名字为:王五
stu2对象的名字为:王五

 

你可能感兴趣的:(java,构造方法,值传递,方法重载,引用传递)