全部章节 >>>>
本章目录
9.1 有参数有返回值的方法
定义方法的目的:
是为了实现特定功能或进行某种运算,无论是实现功能,还是执行运算,都会产生一个结果,而这个结果需要反馈给调用方。
对于方法产生的结果则可通过返回值反馈给调用方。
存在返回值的方法一般有两种形式:无参数有返回值的方法和有参数有返回值的方法。
9.1.1 有参数有返回值的方法的定义和调用
语法:有参数有返回值方法的定义
访问修饰符 返回值类型 方法名(形式参数列表){
方法体;
return 表达式;
}
语法:有参数有返回值方法的调用:
在同一类中调用:
数据类型 变量名 = 方法名(实际参数列表);
在不同类中调用:
数据类型 变量名 = 类名.方法名(实际参数列表);
方法的返回值也称为方法值,通过被调方法中的return 语句实现。
return;或return 表达式;
return 语句是跳转语句,其主要作用如下:
结束被调方法的执行,返回主调方法。
返回一个表达式的值,该值将作为方法调用过程中方法的返回值。
示例:编写程序,在控制台输入一个年份,判断该年份是否为闰年并输出结果。要求定义方法实现闰年的判断,并返回判断结果。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(" 请输入一个年份:");
int year = sc.nextInt();
// 调用方法,并接受返回值
LeapYearDemo lyd = new LeapYearDemo();
boolean result = lyd.isLeapYear(year);
if (result == true)
System.out.printf("%d 为闰年 \n", year);
else
System.out.printf("%d 为平年 \n", year);
}
9.1.2 返回值的传递过程
方法调用时返回值传递的过程
说明:
- 返回值传递的时机:在被调方法执行完毕返回主调方法时。
- 返回值传递的过程:接收返回值的变量 = return 语句之后的表达式的值。
- 返回值传递的意义:将数据从被调方法传递至主调方法的一种方式。
9.1.3 方法返回值的注意事项
(1)方法可以没有返回值,也可以存在返回值,但最多只能存在一个返回值。
(2)方法的返回值可以为变量、常量以及表达式。
(3)在无返回值方法中,方法体内可以没有return 语句,当被调方法执行完毕后,将自动返回至主调方法。也可以使用“return;”语句,结束被调方法的执行,返回主调方法。
(4)在有返回值方法中,方法体中必须包含“return 表达式;”语句。
(5)方法体中返回值的数据类型必须与方法中定义时指定的返回值类型相匹配。
(6)使用条件结构时,必须保证每一个分支都包含返回值。
9.1.4 实践练习
9.2 参数的数据类型
Java 的数据类型分为值类型和引用类型,这两种类型在作为参数使用时是有区别的。
9.2.1 值类型的参数
值类型的参数:
当方法的参数是值类型时,因为值类型变量里存放的即变量的值,形参和实参会完成变量值的拷贝。当方法内代码完成形参值的改变时,实参不会同步改变
示例:修改示例,定义方法实现提薪功能,每位员工的工资涨幅均为20%。
//定义方法实现员工的提薪功能
public void changeValue(int val) {
System.out.println("方法内改变前" + num);
val++;
System.out.println("方法内改变后" + num);
}
MethodParameterDemo mpd = new MethodParameterDemo();
nt num = 100;
System.out.println("调用方法前" + num);
mpd.changeValue(num);
System.out.println("调用方法后" + num);
分析:调用方法时,实参为形参赋值,形参的值发生变化,而实参没有被改变。
值类型的参数,形参改变不会影响实参。
如果开发中参数必须是值类型,但又想通过方法改变,该怎么解决呢?
示例:
public int changeVal(int val) {
val++;
return val;
}
MethodParameterDemo mpd = new MethodParameterDemo();
int num = 100;
System.out.println(" 调用方法前 " + num);
num = mpd.changeVal(num);
System.out.println(" 调用方法后 " + num);
9.2.2 引用类型的参数
- Java中的引用类型变量里存储的是对象的内存地址,通过内存地址可以访问到对象的属性和方法。
- 当引用类型变量完成相互赋值时,即完成对象地址的拷贝,而非对象属性的拷贝。
示例:
public class Person {
int id;
String name;
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
}
public static void main(String[] args) {
Person p1 = new Person(1, "zhangsan");
Person p2 = p1;
System.out.printf("改变前p1的名字是%s,p2的名字是%s\n", p1.name, p2.name);
p2.name = "lisi";
System.out.printf("改变后p1的名字是%s,p2的名字是%s\n", p1.name, p2.name);
}
Person类型为引用类型。变量p1里存放的是内存地址,赋值时两个变量里的地址相同,指向同一个对象。
当我们将引用类型作为方法参数使用时,因为参数的数据类型为引用类型,变量里存放的是对象的内存地址,所以形参和实参实际是同一个对象,改变实参的值,形参也会改变。
示例:
public void changeName(Person p){
if(p != null){
p.name = " 宫城诗 ";
}
}
Person p1 = new Person(1, " 程旭媛 ");
System.out.println(" 调用方法前 p1 的姓名为 "+p1.name);
MethodParameterDemo2 mpd2 = new MethodParameterDemo2();
mpd2.changeName(p1);
System.out.println(" 调用方法后 p1 的姓名为 "+p1.name);
分析:在执行方法时,实参为形参赋值,因为p1对象为引用类型,所以赋值的是对象的内存地址,实参和形参指向的是同一个对象,因此同时改变。
有参方法的调用实际就是实参为形参赋值的过程,形参和实参取值是否同步取决于参数的数据类型,当参数是值类型时,形参和实参的取值是不同步的,当参数是引用类型时,形参和实参的取值是同步的。
9.2.4 实践练习
9.3 深入理解方法
9.3.1 质数的判断
示例:在控制台中输出50~100之间的所有质数。质数是指只能被1和本身整除的数字。例如,7只能被1、7 整除,所以 7 为质数。要求:判断质数的方法实现。
分析:
定义方法isPrimeNumber(),用于实现指定数字是否为质数的判断。
方法签名:public bool IsPrimeNumber(int num)
方法体:质数的判断过程,可使用循环结构实现,从2开始直到num-1,逐一判断是否存在能够整除num的数字,若不存在,则当前数字为质数,否则为非质数。
// 参数 num:需要判断的数字
// 返回值:是否为质数,true:质数,false:非质数
public boolean isPrimeNumber(int num) {
// 声明变量,判断结果
boolean result = true;
// 使用循环,从 2 到 num-1 之间所有数字与 num 进行除法运算
// 若存在能够整除 num 的数字,则 num 为非质数
for (int i = 2; i < num; i++) {
if (num % i == 0) {// 存在整除 num 的数字,num 为非质数,判断结果为 false
result = false;
break; // 跳出循环
}
}
// 返回判断结果
return result;
}
public static void main(String[] args) {
PrimeNumDemo pnm = new PrimeNumDemo();
System.out.println("50 ~ 100 之间所有的质数:");
for (int i = 50; i <= 100; i++) {
// 调用方法,逐一判断 50 ~ 100 之间所有的数字是否为质数
if (pnm.isPrimeNumber(i))
System.out.println(i);
}
}
9.3.2 水仙花数的判断
示例:用户在控制台输入一个三位数字,判断该数字是否为水仙花数。
分析:
定义方法isNarcissus,用户判断参数数字是否为水仙花数,如果是返回true否则返回false。
水仙花数是一个三位数字,三位数字的立方之和等于数字本身。
根据方法功能分析可知,方法isNarcissus需要设置int类型的参数num,表示需要判断的数字,判断后的结果,可通过返回值实现,因此方法isNarcissus的方法签名如下:
public boolean isNarcissus (int num)
public boolean isNarcissus(int num){
if(num >= 100 && num <=999 ){
int singleDigit = num % 10; //获取个位
int tensDigit = num / 10 % 10;//获取十位
int hundredsDigit = num /100;//获取百位
int single = singleDigit * singleDigit * singleDigit ;
int tens = tensDigit * tensDigit * tensDigit;
int hunderds = hundredsDigit * hundredsDigit * hundredsDigit;
if(single + tens + hunderds == num){
return true;
}
}
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数");
int num = sc.nextInt();
NarcissusDemo nd = new NarcissusDemo();
boolean result = nd.isNarcissus(num);
if(result){
System.out.println("您输入的是一个水仙花数");
}
else{
System.out.println("您输入的不是水仙花数");
}
}
9.3.3 实践练习
9.4 方法的使用
9.4.1模拟程序菜单
示例:定义菜单类,在菜单中封装登录菜单与登录后的主菜单。
分析:
定义类。
定义显示登录菜单和主菜单的方法。
public int loginMenu()
public int mainMenu()
编写方法体。
import java.util.Scanner;
public class Menu {
//定义显示登录菜单的方法
public int loginMenu() {
Scanner input = new Scanner(System.in);
int choose = 0;
System.out.println("******************************");
System.out.println("\t1.系统登录");
System.out.println("\t2.退出系统");
System.out.println("*******************************");
System.out.print("请输入选项:");
return choose = input.nextInt();
}
//定义显示主菜单的方法
public int mainMenu() {
Scanner input = new Scanner(System.in);
int choose = 0;
System.out.println("\t欢迎进入电子商务系统");
System.out.println("************************************");
System.out.println("\t1.查看商品");
System.out.println("\t2.我的购物车");
System.out.println("\t3.购物结算");
System.out.println("\t4.注销");
System.out.println("************************************");
System.out.print("请输入选项:");
return choose = input.nextInt();
}
public static void main(String[] args) {
Menu m = new Menu();
int choose = m.loginMenu();
switch (choose) {
case 1:
choose = m.mainMenu();
switch (choose) {
case 1:
System.out.println("开始查看商品");
break;
case 2:
System.out.println("浏览购物车");
break;
case 3:
System.out.println("开始购物结算");
break;
case 4:
System.out.println("注销中……");
break;
}
break;
case 2:
System.out.println("系统退出,期待您的再次使用!");
break;
}
}
}
9.4.2 模拟银行存取款
示例:模拟银行账户存取款以及查看余额功能。要求:将各种业务功能模块分别定义方法实现。
分析:
定义方法queryBalance,用于实现查询余额功能。方法queryBalance的方法签名如下:
public void queryBalance(int balance)
定义方法deposit,用于实现存款功能,方法Deposit的方法签名如下:
public int deposit (int balance)
定义方法withdrawal,用于实现取款功能。方法Withdrawal的方法签名如下:
public int withdrawal(int balance)
在main方法中实现程序的执行流程,并在对应操作中调用方法即可。
import java.util.Random;
import java.util.Scanner;
public class BankDemo {
//取款功能
public int withdrawal(int balance) {
Scanner sc = new Scanner(System.in);
System.out.println("---------取款---------");
System.out.println("请输入取款金额:");
int money = sc.nextInt();
if (balance > money) {
balance -= money;
System.out.println("取款成功");
} else {
System.out.println("余额不足,取款失败");
}
return balance;
}
//存款功能
public int deposit(int balance) {
Scanner sc = new Scanner(System.in);
System.out.println("---------存款---------");
System.out.println("请输入存款金额:");
int money = sc.nextInt();
balance += money;
System.out.println("存款成功");
return balance;
}
//查询余额功能
public void queryBalance(int balance) {
System.out.println("---------查询---------");
System.out.println("您的余额:" + balance);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BankDemo bd = new BankDemo();
int choose;
Random rdm = new Random();
int balance = rdm.nextInt(1000);// 余额为0~999之间的数字
System.out.println("服务种类:");
System.out.println("【1】查看余额");
System.out.println("【2】取款");
System.out.println("【3】存款");
System.out.println("【0】退出");
//省略其他菜单
do {
System.out.println("请选择:");
choose = sc.nextInt();
switch (choose) {
case 1:
bd.queryBalance(balance);
break;
case 2:
bd.withdrawal(balance);
break;
case 3:
bd.deposit(balance);
break;
case 0:
System.out.println("欢迎下次继续使用!");
break;
default:
System.out.println("您输入的有误,请重新输入");
}
} while (choose != 0);
}
}
9.4.3 实践练习
总结:
- return 语句是Java语言中的跳转语句,主要作用:结束被调方法的执行,返回主调方法;返回一个表达式的值;
- 返回值传递的过程其实就是一个赋值的过程,将return 语句之后的表达式的值赋值给主调方法中用于接收返回值的变量。
- 方法可以没有返回值,也可以存在返回值,但最多只能存在一个返回值。
- 值类型变量里存放的时值本身,引用类型变量里存放的时地址。
- 当参数是值类型时,形参和实参的取值是不同步的,当参数是引用类型时,形参和实参的取值是同步的。