智渔课堂官方免费教程八:Java基础之方法(函数)

方法(C语言中称为函数)

方法:由多条语句组成,可以重复使用的,完成一个或多个功能的代码集合;方法只能声明在类中,不能声明在其他方法中
语法格式:
[访问修饰符] 返回值类型 方法名([参数列表]){
 //代码块 

注:这里的中括号[]代表括号里的内容可以写也可以不写,如果写,中括号不用写
例如:
/**
 * 演示方法的声明和调用
 * @author 学霸联盟 - 赵灿
 */
public class MethodDeclareDemo {
	/**
	 * 声明了一个没有参数的方法,方法名为m1
	 * 方法体也是空的,表示这个方法什么都没做
	 */
	void m1(){}
	/**
	 * 声明了一个带两个参数的方法,方法名为m2
	 * 这里的两个参数,本质就是声明变量,称为形式参数,简称形参
	 * 当这个方法被调用时,按照形参的顺序,传入对应数据类型的值或变量
	 * 被传入的值称为实际参数,简称形参
	 * 该方法的方法体中有一条输出语句,输出传入两个参数的值,这就是方法的功能
	 */
	void m2(String name, int age){
		System.out.println("姓名:" + name + "  年龄:" + age);
	}
	/**
	 * 这也是一个方法,方法名是main,有一个String[]类型的参数
	 * 只不过这个方法比较特殊,是程序的入口
	 */
	public static void main(String[] args){
		//创建一个MethodDeclareDemo类的对象
		MethodDeclareDemo mdd = new MethodDeclareDemo();
		//调用方法m1,m1这个方法什么都没有做
		mdd.m1();
		/*
		 * 调用方法m2,由于m2声明了参数,调用时必须传入实参
		 * "张三"和18就是传递给方法m2的实参
		 * 参数传递过程相当于赋值操作
		 * 程序执行mdd.m2("张三", 18);这条语句时
		 * 会将"张三"赋值给形参name(相当于String name = "张三")
		 * 18赋值给形参age(相当于int age = 18)
		 */
		mdd.m2("张三", 18);
	}
}
运行结果:姓名:张三  年龄:18
方法的参数:就是在方法的小括号中声明的变量,这个变量称为:形式参数,简称:形参;用于接收调用时传入的值(实参),形参的使用范围是整个方法,多个参数中间用英文格式的逗号隔开;当带有参数的方法被调用时,必须对应方法声明时编写的参数类型和顺序,给这个方法传入实际的值;这个实际值称为实际参数(简称:实参);
返回值类型:必须写,如果一个方法不需要返回值,返回值类型写void
返回值:方法执行完毕后,返回给调用者的结果;使用关键字return返回,并且返回的值要和返回值类型匹配;格式:return 返回值; 
关键字return:用在方法中,作用是结束整个方法;

例如:某人要去手机店买一部手机,那么他需要先给钱,然后获得手机。其中给的钱就是实参,手机就是返回值
实例:
/**
 * 样式方法的返回值类型和返回值
 * @author 学霸联盟 - 赵灿
 */
public class Person {
	/*
	 * 声明一个方法名为buy的方法,有一个类型为double的形式参数money
	 * 返回值的类型是String,那么在方法中必须使用关键字return,返回一个String类型的值
	 */
	String buy(double money) {
		// 声明String类型的变量phone
		String phone;
		// 判断传入的钱是否大于6000
		if (money > 6000) {
			// 如果大于6000,就给变量phone赋值为“苹果手机”
			phone = "苹果手机";
		} else {
			// 如果不大于6000,就给变量phone赋值为“华为手机”
			phone = "华为手机";
		}
		/*
		 * 因为当程序执行到方法调用语句时,程序会跳转到被调用的方法中执行
		 * 当方法被执行完之后,又会返回到方法调用语句处
		 * 所以方法中使用关键字return返回的结果被称为返回值
		 * 当方法声明的返回值类型不是void时,方法中必须使用return语句返回一个返回值
		 * 此处phone就是返回值
		 */
		return phone;
	}
	/*
	 * 声明一个不带参数的方法,方法名为call
	 * 声明返回值类型为void代表这个方法没有返回值
	 * 方法中也可以写return语句,也可以不写
	 * 如果写return后面只能跟英文格式的分号; 即:return;
	 */
	void call() {
		/*
		 * 此处声明一个String类型的变量myPhone,来接收buy方法的返回值
		 * 因为buy的返回值类型是String,所有此处用String类型的变量接收
		 * 相当于String myPhone = phone(buy方法中return后面的phone)
		 * 当程序执行buy(1000.0);语句调用buy方法时,程序会跳到buy方法中执行
		 * 直到遇到buy方法中的return语句后
		 * 再返回到此处执行赋值语句(将buy方法返回的结果赋值给变量myPhone)
		 */
		String myPhone = buy(1000.0);
		System.out.println("使用\"" + myPhone + "\"拨打电话...");
		/*
		 * return语句可有可无
		 * 需要注意的是,执行return语句后方法就结束了
		 * 所以return语句后面还有语句的话就不会被执行
		 */
		return;
		//以下位置(此处开始至方法的右大括号之间)再写代码就会提示错误
	}

	public static void main(String[] args) {
		//创建一个人类的对象
		Person person = new Person();
		/*
		 * 程序由main方法进入执行
		 * 执行到此处调用call方法,程序会跳到call方法中执行
		 * 当call方法中遇到return或所有代码都执行完成(未写return语句时)后
		 * 再回到当前位置,执行后面的输出语句
		 */
		person.call();
		//call方法执行完成后,继续执行此句
		System.out.println("main方法的最后一句代码");
	}
}
运行结果:
使用"华为手机"拨打电话...
main方法的最后一句代码

方法调用语句

语法格式:对象名.方法名();或 类名.静态方法名();(下面讲到) 
例如上例中用到的 person.call();

方法传参

值传递(基本数据类型)

将实参变量中保存的值复制一份,赋值给形参变量;赋值之后实参变量和形参变量没有任何关系,修改任何一个变量,另一个变量都不会发生变量

引用传递(引用类型,String除外)

将实参变量中存储的对象的内存地址复制一份赋值给形参变量,此时实参变量和形参变量中保存的是同一个对象的内存地址;使用任何一个引用对对象的属性进行修改,再次使用任何一个引用访问对象被修改的属性时都会发生变化。
/**
 * 声明汽车类Car
 * @author 学霸联盟 - 赵灿
 */ 
class  Car{
	//声明一个String类型的变量name
	String carName;
	//声明一个变量color代表汽车的颜色,并赋值
	String  color = "无色";
}
/**
 * 声明汽车工厂类CarFactory
 * @author 学霸联盟 - 赵灿
 */ 
class CarFactory{
	/**
	 * 声明一个结账的方法
	 * 用于测试参数的值传递
	 * 参数money用于接收用户付款
	 */
	void settlement(double money){
		System.out.println("用户付款:" + money);
		//修理费150
		double repairs = 150;
		//对变量money进行修改,得到收取修理费剩余的钱
		money = money - repairs;
		System.out.println("应找零:" + money);
	}
	/**
	 * 声明一个修改汽车颜色的方法
	 * 用于测试参数的引用传递
	 * 参数car用于接收被修改颜色的汽车
	 */
	void setColor(Car car) {
		// 将接收到的汽车的颜色设置成黑色
		car.color = "黑色";
	}
}

/**
 * 演示值传递和引用传递
 * 
 * @author 学霸联盟 - 赵灿
 */
public class ParameterTransferDemo {
	// 声明一个main方法,作为程序的入口
	public static void main(String[] args) {
		System.out.println("------------ 引用传递 ------------");
		//使用关键字new创建汽车对象,并将对象在内存中的地址赋值给变量c
		Car c = new Car();
		c.carName = "小c";
		System.out.println("刚刚创建出来的汽车\"" + c.carName + "\"的颜色是:" + c.color);
		//创建汽车工厂对象cf
		CarFactory cf = new CarFactory();
		//引用传递:将变量c中存储的地址,传递给setColor方法的参数car
		cf.setColor(c);
		//输出结果汽车的名字还是小c,这表明汽车还是原来的汽车,但是颜色已经变了
		System.out.println("通过汽车工厂修改后\"" + c.carName + "\"的颜色是:" + c.color);
		
		System.out.println("------------- 值传递 -------------");
		double myMoney = 200;
		System.out.println("付款前我的钱是:" + myMoney);
		//值传递:调用结算的方法settlement,将myMoney的值传给参数money
		cf.settlement(myMoney);
		System.out.println("付款后我的钱是:" + myMoney);

		/*
		 * 前面说过,方法的传参相当于用实参给形参赋值
		 * 下面这段代码中,变量c1代表上面的变量c
		 * 变量c2代表setColor方法中的参数car
		 */
		System.out.println("------------ 引用传递 ------------");
		//创建一个汽车对象,并将汽车对象在内存中的地址赋值给变量c1
		Car c1 = new Car();
		//设置名称
		c1.carName = "小c1";
		//由于引用类型变量中存储的是对象在内存中的地址
		//所以引用类型的变量也称为引用
		Car c2 = c1;
		System.out.println("修改前汽车c1的名称:" + c1.carName + "  颜色:" + c1.color);
		System.out.println("修改前汽车c2的名称:" + c2.carName + "  颜色:" + c2.color);
		//对c2的修改会影响c1,c1跟着变化
		c2.color = "黑色";
		System.out.println("修改后汽车c1的名称:" + c1.carName + "  颜色:" + c1.color);
		System.out.println("修改后汽车c2的名称:" + c2.carName + "  颜色:" + c2.color);
		
		System.out.println("------------- 值传递 -------------");
		double m1 = 200;
		double m2 = m1;
		System.out.println("修改前m1的值:" + m1);
		System.out.println("修改前m2的值:" + m2);
		//对m2的修改不会影响m1
		m2 = m2 - 150;
		System.out.println("修改后m1的值:" + m1);
		System.out.println("修改后m2的值:" + m2);
	}
}
运行结果:
------------ 引用传递 ------------
刚刚创建出来的汽车"小c"的颜色是:无色
通过汽车工厂修改后"小c"的颜色是:黑色
------------- 值传递 -------------
付款前我的钱是:200.0
用户付款:200.0
应找零:50.0
付款后我的钱是:200.0
------------ 引用传递 ------------
修改前汽车c1的名称:小c1  颜色:无色
修改前汽车c2的名称:小c1  颜色:无色
修改后汽车c1的名称:小c1  颜色:黑色
修改后汽车c2的名称:小c1  颜色:黑色
------------- 值传递 -------------
修改前m1的值:200.0
修改前m2的值:200.0
修改后m1的值:200.0
修改后m2的值:50.0

构造方法(构造器)

使用new关键字创建对象时会被调用,一般用于初始化类中的一些变量。
语法格式:[访问修饰符] 类名([参数列表]){ //方法体 }
实例:
/**
 * 演示构造方法
 * @author 学霸联盟 - 赵灿
 */ 
public class CustomerDemo {
	String name;
	/**
	 * 构造方法的方法名必须严格和类名一致
	 * 不能有返回值类型
	 * 如果不写,系统自动提供一个没有参数的构造方法
	 * 如果写了,无论写的构造方法带不带参数,系统都不再系统无参构造
	 */
	CustomerDemo(String str) {
		//初始化:第一次赋值
		name = str;
	}
	
	public static void main(String[] args) {
		/*
		 * 通过new创建对象时,会先将变量name加载到内存中,然后执行构造方法
		 * 由于在CustomerDemo类中声明了带一个String类型参数的构造方法
		 * 所以系统将不会再为CustomerDemo类提供无参的构造方法了
		 * 所以使用new创建对象时必须传入参数
		 */
		CustomerDemo cd = new CustomerDemo("abc");
		//输出结果:abc
		System.out.println(cd.name);
	}
}
运行结果:abc
注意: 1、没有返回值类型,方法名和类名完全一致(包括大小写也必须一致)
2、使用new创建对象时,先将在堆中创建一块内存空间,将属性加载到这块内存空间中,然后执行构造方法
3、如果不写构造方法,系统会自动提供一个无参的构造方法
4、如果写了构造方法,系统将不再提供无参构造
5、如果构造方法前写了返回值类型,该方法便不是构造方法了,只不过是一个名字和类名相同的普通方法


构造方法和普通方法的区别

1、 返回值类型:构造方法没有返回值类型,普通方法必须有(如果不需要返回值,写void)
2、 方法名:构造方法的方法名和类名完全一致(包括大小写也必须一致),普通方法的方法名自定义
3、 构造方法可以使用关键字this、super调用,new操作时也会调用,普通方法是用对象名.方法名();的方法调用
4、 一个类中,如果不写构造方法,系统会自动提供一个无参的构造方法;如果写了构造方法,系统将不再提供无参构造;
5、 如果构造方法前写了返回值类型,该方法便不是构造方法了,只不过是一个名字和类名相同的普通方法

方法的重载:@Overload

方法重载是描述同一个类中,相同方法名之间的关系。
无论是普通方法还是构造方法,都可以被重载。
例如:一个类中包含多个构造方法和多个同名的方法
/**
 * 演示方法的重载(overload)
 * @author 学霸联盟 - 赵灿
 */ 
public class OverloadDemo {
	String str;
	/*
	 * 创建了两个构造方法,这两个构造方法就构成了重载
	 */
	OverloadDemo(){}
	OverloadDemo(String s){
		str = s;
	}
	
	/*
	 * 创建了两个普通方法
	 * 两个方法的方法名相同,参数列表不同
	 * 他们也构造了方法重载
	 * 但是如果两个方法名相同,参数列表也相同,就会导致方法同名的错误
	 */
	void m1(){}
	void m1(String s){
		str = s;
	}
	
	public static void main(String[] args) {
		//这种方式创建对象时会调用类的无参构造
		OverloadDemo od1 = new OverloadDemo();
		//这种方式创建对象,会调用类中带一个String类型参数的构造方法
		OverloadDemo od2 = new OverloadDemo("abc");
		//输出结果:null
		System.out.println(od1.str);
		//输出结果:abc
		System.out.println(od2.str);
	}
}
运行结果:
null
abc

方法重载需要满足的条件:

1、在同一类中
2、方法名相同
3、参数列表不同
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章