##################################################
目录
方法定义有返回值 but 调用该方法后 没有对返回值做任何处理
##################################################
——————————
我们知道 类的方法是一个功能模块 作用就是 做一件事情/实现某个独立的功能
还能供多个地方使用!
我们已经能够使用方法实现一定的功能 并且在类中、在不同文件中灵活运用
我们当然不能满足于此
带参方法 能够根据不同的外界条件得到不同的结果
带参方法使得程序具有更高的灵活性
- 有没有用过 榨汁机?
- 假设有一个榨汁机类 有一个榨汁方法 则:
- 我们放进去香蕉 得到的是香蕉汁的结果 参数值为 香蕉
- 我们放进去荔枝 得到的是荔枝汁的结果 参数值为 荔枝
- 我们放进去草莓 得到的是草莓汁的结果 参数值为 草莓
- 如果什么都不放 就无法榨汁!或者默认结果榨出的是清水汁……
- 所以我们在使用榨汁机时 必须提供一个被榨的水果!
- 此时不同的水果就是不同的参数!
-
- 取过钱吧?
- 假设 ATM 类有一个吐纸币方法
- 首先要输入一定的金额 然后 ATM 才会 吐出 一定的纸币
- 此时不同的金额数就是参数
可以看出 方法中某种功能的实现依赖于我们给她的初始信息
这时候在定义方法时就需要在括号内加入参数列表
如果不能看懂我在说什么 那你一定前面没好好学 回过头去看看吧。。
——————————
另外 现在总结出来了什么是声明和定义了吗?
这俩并不是一个东西。。 一个是声明 一个是实施
- 声明 是关键字声明 告诉编译器要干嘛
- 定义 才是代码的实现 编译器才知道要具体要怎么做
其实 我们现在才算是真正接触方法!
语法:
- 访问修饰符 返回值类型 方法名(参数列表) {
-
-
- /* 方法主体 */
- }
访问修饰符
就是指该方法允许被访问的权限范围
可以是 public/protected/private 等
如果是 public 访问修饰符 表示该方法可以被任何其她代码调用
返回值类型
表示方法返回值的类型 这个类型为基本数据类型
如果方法不返回任何值 就必须声明为 void 类型
Java 对待返回值的要求非常严格!使用 return 语句返回
方法的返回值类型必须与所说明的类型相匹配
方法名
就是定义方法的名字 必须使用合法的标识符
参数列表
就是传送给方法的参数类型 列表中的多个参数之间可以用逗号隔开
单个参数格式:
数据类型 参数
多个参数格式:
数据类型 参数_1, 数据类型 参数_2, 数据类型 参数_N
参数可以有一个或多个
如果为 void 或者空表示没有参数 这时的方法就是我们上之前的无参方法了
示例 code :
- public class Test {
-
- String name[] = new String[100]; /* 姓名数组 */
-
- /* 带参方法 */
- public void addName(String Name) {
-
- /* 增加姓名方法 */
- }
-
- /* 无参方法 */
- public void showName() {
-
- /* 显示姓名方法 */
- }
- }
成员属性除了是变量 也可以是数组
同样可以被引用后通过点操作符来进行访问 数组成员/数组成员的元素
##################################################
——————————
调用带参方法与调用无参方法的语法相同 就是带参方法调用时必须传入实际的参数值
语法:
对象名.方法名(参数_1, 参数_2, 参数_N);
——————————
形参 就是形式参数 形式参数是参数类型
实参 就是实际参数 实际参数是参数的值
一个是类型 一个是值
形参是在定义方法的时候对参数的称呼
目的就是定义方法需要传入的参数个数和类型
实参就是在调用方法时传递给方法处理的实际的值
这里萌新很不好弄明白绕不过来!
——————————
调用带参方法时 需要注意
如果不在一个类中则首先要先实例化对象 再调用方法
实参的 类型、数量、顺序 都要与形参一一对应!!
语法格式:
- 类名 对象名 = new 类名();
- 对象名.方法名(参数列表);
——————————
循环增加姓名并输出示例程序
Main.java code:
- import java.util.Scanner;
-
- public class Main {
-
- public static void main(String[] args) {
-
- Scanner sc = new Scanner(System.in); /* 实例化 Scanner 对象 */
- Test test = new Test(); /* 实例化 Test 对象 */
-
- /* 循环录入新名字 */
- System.out.print ( "请输入 5 个姓名 <<< " ); /* 交互信息 */
- for (int i = 0; i < 5; i ++) {
- /* 条件 仅仅录入 5 个 因为我懒!!。。 */
-
- String newName = sc.next(); /* 得到新名字 */
- test.addName ( newName ); /* 录入新名字 */
- }
-
- /* 显示全部名字 */
- System.out.println();
- test.showName();
- }
- }
-
- class Test {
-
- String name[] = new String[100]; /* 姓名数组 */
- int i = 0; /* 下标记录 */
-
- public void addName(String Name) {
- /* 带参方法 增加一个姓名方法 */
-
- name[i] = Name; /* 接收值 录入姓名数组 */
- /* Name 在哪里声明的 看看此方法的括号? */
-
- i ++; /* 下标 +1 */
- }
-
- public void showName() {
- /* 无参方法 输出姓名数组方法 */
-
- System.out.println ( "显示所有姓名 >>> " ); /* 交互信息 */
-
- for ( String i : name ) {
- /* 使用增强 for 遍历姓名数组 */
-
- if (i == null)
- /* 遇到未处理的值就退出 */
- break;
-
- /* 有值就输出 */
- System.out.println ( i +" " );
- }
- }
- }
gnome-terminal cmd:
- [lilian@CentOS javaTest]$ javac Main.java
- [lilian@CentOS javaTest]$ java Main
- 请输入 5 个姓名 <<< 李恰恰
- 李哈
- 李二哈
- 老姐姐诶
- 汪汪
-
- 显示所有姓名 >>>
- 李恰恰
- 李哈
- 李二哈
- 老姐姐诶
- 汪汪
- [lilian@CentOS javaTest]$ java Main
- 请输入 5 个姓名 <<< 李恰恰 李哈 李二哈 老姐姐诶 汪汪
-
- 显示所有姓名 >>>
- 李恰恰
- 李哈
- 李二哈
- 老姐姐诶
- 汪汪
- [lilian@CentOS javaTest]$
看 可以很明显的看出 确实传递参数成功了!
不过 弄明白 addName 方法中的 Name 在哪声明了吗?
没错 在后面的括号内 参数列表声明的参数在整个方法内都是可以使用的:
- public void addName ( String Name ) {
-
- name[i] = Name;
- i ++;
- }
然后你再看看传参调用代码:
- String newName = sc.next();
- test.addName ( newName );
发现参数名字不一样真的没问题吗?
我告诉你 没问题的 她们根本不关心名字的问题 只负责接收值!
所以 她们关心的只是数据的类型 和 参数的个数
仅仅关心形参!! 实参才是你输入要传递的值!!
——————————
很简单的 定义时定义指定的接收数据类型、个数
调用时 也指定相应的形参数据类型、个数
这就 ok 了
例如 我们在指定区间查找姓名 并显示是否查找成功
我们在数组的某个区间中查询学生姓名 设计方法时要考虑传递 3 个参数
开始位置、结束位置、查找姓名
Main.java code:
- import java.util.Scanner;
-
- public class Main {
-
- public static void main(String[] args) {
-
- Scanner sc = new Scanner(System.in);
- Test test = new Test();
-
- System.out.print("请输入 5 个姓名 >>> ");
- for ( int i = 0; i < 5; i ++ ) {
-
- String newName = sc.next();
- test.addName ( newName );
- }
-
- System.out.println();
- test.showName();
-
- for ( ; ; ) {
- /* 开始查找指定区间名字 */
-
- System.out.println();
-
- System.out.print ( "请输入开始查找的位置 <<< " );
- int start = sc.nextInt();
-
- System.out.print ( "请输入结束查找的位置 <<< " );
- int end = sc.nextInt();
-
- System.out.print("请输入查找的姓名 <<< ");
- String findName = sc.next();
-
- System.out.println ( "\n*****查找结果*****" );
- if ( test.searchName ( start, end, findName ) )
- System.out.println ( "找到了!!!" );
- else
- System.out.println ( "没有找到..." );
-
- /* 是否退出循环 */
- System.out.print ( "\n继续吗 y/n <<< " );
- char Y_N = sc.next().charAt(0);
- if ( Y_N == 'y' )
- continue;
- if ( Y_N == 'n' )
- break;
-
- System.out.println();
- }
- }
- }
-
- class Test {
-
- String name[] = new String[100]; /* 姓名数组 */
- int i = 0; /* 下标记录 */
-
- public void addName(String Name) {
-
- name[i] = Name;
- i ++;
- }
-
- public void showName() {
-
- System.out.println ( "显示所有姓名 >>> " );
-
- for ( String i : name ) {
- /* 遍历姓名数组 */
-
- if (i == null)
- /* 遇到未处理的值就退出 */
- break;
-
- System.out.println ( i + " " ); /* 有值就输出 */
- }
- }
-
- public boolean searchName ( int Start, int End, String Name ) {
- /* 多参方法 查找指定区间姓名 */
-
- boolean find = false; /* 是否找到标识 */
-
- for ( int i = Start - 1; i < End; i ++ ) {
- /* 在指定的数组区间查找姓名 */
-
- if ( name[i].equals( Name ) ) {
- /* 如果找到标识 结束查找 返回真值 */
-
- find = true;
-
- break;
- }
- }
-
- /* 返回真假值 */
- return find;
- }
- }
Bash demo:
- [lilian@CentOS javaTest]$ javac Main.java
- [lilian@CentOS javaTest]$ java Main
- 请输入 5 个姓名 >>> 第一个/0 第二个/1 第三个/2 第四个/3 第五个/4
-
- 显示所有姓名 >>>
- 第一个/0
- 第二个/1
- 第三个/2
- 第四个/3
- 第五个/4
-
- 请输入开始查找的位置 <<< 1
- 请输入结束查找的位置 <<< 5
- 请输入查找的姓名 <<< 第五个/4
- *****查找结果*****
- 找到了!!!
- 继续吗 y/n <<< y
- 请输入开始查找的位置 <<< 1
- 请输入结束查找的位置 <<< 4
- 请输入查找的姓名 <<< 第五个/4
-
- *****查找结果*****
- 没有找到...
-
- 继续吗 y/n <<< n
- [lilian@CentOS javaTest]$
searchName() 有 3 个参数
数据类型分别是 int、int、String
调用该方法的
- Test test = new Test();
- test.searchName(start, end, findName)
参数中的 start、end、findName 的类型也与之一一对应 并且 searchName() 定义的返回值类型为 boolean 类型
返回的 find 类型也为 boolean 类型
##################################################
——————————
- 我们可以看出 使用方法可以提高代码重用率以及程序的效率
- 为了完成不同功能的代码 可以写出不同的方法
- 每一个方法完成一个独立的功能模块 在需要的时候调用就行了
带参 声明方法 定义好参数类型、数量 传送好参数类型数量
这就没啦 就这么简单
我知道 再简单的事 到萌新那里 总是会出问题。。
我当初摸索 C 的时候 一个函数间的传值调用我死活搞不懂
值是怎么传递的?
当你有这个问题的时候 证明前面没学好
就不要学后面的了 先回过头去学前面的 前面的学不好 后面的也学不懂
带参方法的定义对初学者来说 总是会出现各种不可避免的错误
例如 数据类型错误、参数传递错误 等。。
——————————
在调用带参方法时 不应该在传递的实参前添加数据类型
error code:
- public void errors(String error) {
- /* 方法定义 */
-
- /* 方法体 */
- }
-
- 对象名.errors( String "错误的例子" ); /* 方法调用 */
correct code:
对象名.errors("正确的例子"); /* 方法调用 */
——————————
error code:
- public void errors(int error_1, int error_2, String error_3) {
- /* 方法定义 */
-
- /* 方法体 */
- }
-
- String error_1 = "1"; /* int error_1 故意 String */
- int error_2 = 10;
- String error_3 = "错误的例子";
- 对象名.errors ( error_1, error_2, error_3 ); /* 方法调用 */
correct code:
- int correct_1 = 1; /* 修正实参类型 */
- int correct_2 = 10;
- String correct_3 = "正确的例子";
- 对象名.errors ( correct_1, correct_2, correct_3 ); /* 方法调用 */
——————————
error code:
- public void errors(int error_1, String error_2, String error_3) {
- /* 方法定义 */
-
- /* 方法体 */
- }
-
- int error_1 = "1";
- String error_2 = "错误的例子";
- 对象名.errors(error_1, error_2); /* 方法调用 接收三个参数这边只传送两个参数 */
correct code:
- int correct_1 = 1;
- String correct_2 = "正确的例子";
- String correct_3 = "传参的数量类型必须一致";
- 对象名.errors ( correct_1, correct_2, correct_3 ); /* 方法调用 这次传送三个参数 */
——————————
这种情况 在语法结构上来说 并不能称之为结构错误
可是从程序设计来说 算是程序设计的一种
error/correct code:
- public boolean errors ( int A, int B, int C ) {
- /* 方法定义 返回 boolean */
-
- /* 方法体 */
-
- return 布尔值;
- }
-
- int a = 1;
- int b = 2;
- int c = 3;
- 对象名.errors ( a, b, c ); /* 方法调用完之后没有对返回值做任何处理 编译器不会报错... ... */