day 11 课堂笔记
1、方法
1.1、什么是方法,有什么用?
方法(英语单词method)是可以完成某个特定功能的并且可以被重复利用的代码片段。在c语言中,方法被称为“函数”。在java中不叫函数,叫做方法
对于一个java程序来说,如果没有“方法”,会存在什么问题?
代码无法得到复用。提高复用性:定义方法,然后需要使用该代码的功能的时候,直接调用一下方法就可,这样代码就得到复用了。
// 需求1:请编写程序,计算100和200的求和
int x = 100;
int y = 200;
int z = x + y;
System.out.println(x + "+" + y + "=" + z);
// 需求2:请编写程序,计算666和888的求和
// 这个需求2实际上和需求1是完全相同的,只不过具体求和时的“数据不同”
int a = 666;
int b = 888;
int c = a + b;
System.out.println(a + "+" + b + "=" + c );
// 需求1和需求2本质上相同,只不过参与运算的数值不同,代码编写了两份,显然代码没有得到重复利用,专业术语叫做“复用性”差。
功能/业务逻辑既然相同,为什么要重复编写代码,代码能不能写一次,以后要是需要再次使用该业务或者需求的时候,直接调用就可以了。
如果要达到代码复用,那么需要学习java语言中的方法机制
main方法不需要程序员手动调用,是由JVM调用的。但是除了main方法之外其他的方法,都需要程序员手动调用,方法只有在调用的时候才会执行,方法不调用是不会执行的
// 以下的程序是一个体验程序,你看不懂,只需要体验就行了,体验一下方法的好处
public class MethodTest02{
// 主方法,入口。
public static void main(String[] args){
//需求1:编写程序,计算100和200的和
sumInt(100,200);
//需求2:编写程序,计算666和888的和
sumInt(666,888);
//需求3:编写程序,计算111和222的和
sumInt(111,222);
}
// 专门在这个类体中定义一个方法,这个方法专门来完成求和。
public static void main sumInt(int x, int y){
int z = x + y;
System.out.println(x + "+" + y + "=" + z);
}
}
// x y z 在以下的sumInt方法中都属于局部变量。局部变量有一个特点:方法结束之后,局部变量占用的内存会自动释放。
(这里并没有讲解方法的定义,以及方法的调用)
方法定义在类体当中,方法定义的先后顺序没有关系
你定义了一个方法出来,但这个方法无法完成某个功能,那么你抽取的这个方法毫无意义。一般一个方法就是一个“功能单元”。假设在以后的开发中,某个功能是可以独立抽取出来的,建议定义为方法,这样以后只要需要这个功能,那么直接调用这个方法即可,而不需要重复编写业务逻辑代码。
1、方法怎么定义?语法机制是什么?
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
注意:以上中括号[ ] 里卖的内容表示不是必须的,是可选的,方法体由java语句构成。
方法定义之后需要去调用,不调用是不会执行的
1.1、关于修饰符列表:
修饰符列表不是必选项,是可选的。目前为止,大家统一写成:public static 后面就懂应该怎么写了
1.2、关于返回值类型:
第一:返回值类型可以是任何类型,只要是java中合法的数据类型就行,数据类型包括基本数据类型和引用数据类型,也就是说返回值类型可以是:byte short int long float double boolean char string........
第二:什么是返回值?
返回值一般指的是一个方法执行结束之后的结果。结果通常是一个数据,所以被称为“值”,而且还叫“返回值”
方法就是为了完成某个特定的功能,方法结束之后大部分情况下都是有一个结果的,而体现结果的一般都是数据。数据得有类型。这就是返回值类型。
方法执行结束之后的返回值实际上是给调用者了。谁调用就返回给谁。
第三: 当一个方法执行结束不返回任何值的时候,返回值类型也不能空白,必须写上void关键字。所以void表示该方法执行结束后不返回任何结果。
第四:如果返回值类型不是void,那么你在方法体执行结束的时候必须使用“return 值;”这样的语句来完成“值”的返回,如果没有“return 值;” 这样的语句 那么编译器会报错
return 值; 这样的语句作用是什么? 作用是“返回值”,返回方法的执行结果
第五:只要有“return”关键字的语句执行,当前方法必然结束。 return只要执行,当前所在的方法结束,记住:不是整个程序结束。
第六:如果返回值类型是void,那么在方法体当中不能“return 值;” 这样的语句。但是可以有“return;”语句。这个语句“return;”的作用就是用来终止当前方法的
第七:除了void之外剩下的都必须有“return 值;”这样的语句
1.3、方法名
方法名要见名知意。(驼峰命名方式)
方法名在标识符命名规范当中,要求首字母小写,后面每个单词首字母大写,只要是合法的标识符就行。
1.4、形式参数列表
简称:形参
注意:形式参数列表中的每一个参数都是:“局部变量”,方法结束之后内存释放。形参的个数是:0~N个
public static void sumInt(){}
public static void sumInt(int x){}
public static void sumInt(int x , int y){}
public static void sum(int a ,int b, double d ,String s){}
形参有多个的话使用逗号隔开。
形参的数据类型起决定性作用,形参对应的变量名是随意的。
1.5、方法体:
由java语句构成。java语句以“;”结尾。
方法体当中编写的是业务逻辑代码,完成某个特定功能。方法体中代码自上向下执行。方法体中处理业务逻辑代码的时候需要数据,数据来源就是形式参数。
pubic class MethodTest03{
// main方法结束之后不需要给JVM返回任何执行结果
public static void main(String[] args){
}
}
1、方法怎么定义,语法机制是什么?
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
注意:
[] 符号叫做中括号,以上中括号[]里面的内容表示不是必须的,是可选的。
方法体由Java语句构成。
方法定义之后需要去调用,不调用是不会执行的。
1.1、关于修饰符列表:
修饰符列表不是必选项,是可选的。目前为止,大家统一写成:public static
后面你就理解应该怎么写了。
1.2、关于返回值类型:
第一:返回值类型可以是任何类型,只要是java中合法的数据类型就行,数据
类型包括基本数据类型和引用数据类型,也就是说返回值类型可以是:byte short
int long float double boolean char String......
第二:什么是返回值?
返回值一般指的是一个方法执行结束之后的结果。
结果通常是一个数据,所以被称为“值”,而且还叫
“返回值”。
方法就是为了完成某个特定的功能,方法结束之后
大部分情况下都是有一个结果的,而体现结果的一般
都是数据。数据得有类型。这就是返回值类型。
main{
// 调用a方法
a();..如果a方法执行结束之后有返回值,这个返回值返回给main了。
}
a(){}
方法执行结束之后的返回值实际上是给调用者了。谁调用就返回给谁。
第三:当一个方法执行结束不返回任何值的时候,返回值
类型也不能空白,必须写上void关键字。所以void表示该
方法执行结束后不返回任何结果。
第四:如果返回值类型“不是void”,那么你在方法体执行结束的时候必须使用
"return 值;"这样的语句来完成“值”的返回,如果没有“return 值;”这样的语句
那么编译器会报错。
return 值; 这样的语句作用是什么?作用是“返回值”,返回方法的执行结果。
第五:只要有“return”关键字的语句执行,当前方法必然结束。
return只要执行,当前所在的方法结束,记住:不是整个程序结束。
第六:如果返回值类型是void,那么在方法体当中不能有“return 值;”这样的
语句。但是可以有“return;”语句。这个语句“return;”的作用就是用来终止当前
方法的。
第七:除了void之外,剩下的都必须有“return 值;”这样的语句。
1.3、方法名
方法名要见名知意。(驼峰命名方式)
方法名在标识符命名规范当中,要求首字母小写,后面每个单词首字母大写。
只要是合法的标识符就行。
1.4、形式参数列表
简称:形参
注意:形式参数列表中的每一个参数都是“局部变量”,方法结束之后内存释放。
形参的个数是:0~N个。
public static void sumInt(){}
public static void sumInt(int x){}
public static void sumInt(int x, int y){}
public static void sum(int a, int b, double d, String s){}
形参有多个的话使用“逗号,”隔开。逗号是英文的。
形参的数据类型起决定性作用,形参对应的变量名是随意的。
1.5、方法体:
由Java语句构成。java语句以“;”结尾。
方法体当中编写的是业务逻辑代码,完成某个特定功能。
在方法体中的代码遵循自上而下的顺序依次逐行执行。
在方法体中处理业务逻辑代码的时候需要数据,数据来源就是这些形参。
2、方法定义之后怎么调用呢?
方法必须调用才能执行。
怎么调用,语法是什么?
类名.方法名(实际参数列表);
实参和形参的类型必须一一对应,另外个数也要一一对应。
*/
public class MethodTest03{
//方法定义在这里可以。
// main方法结束之后不需要给JVM返回任何执行结果。
public static void main(String[] args){
// 调用方法
//错误: 不兼容的类型: String无法转换为int
//MethodTest03.divide("abc", 200);
//这就像你这么写 int a = "abc";
//错误原因: 实际参数列表和形式参数列表长度不同
//MethodTest03.divide();
// (10, 2)叫做实际参数列表,简称实参。
// 注意:实参和形参必须一一对应,类型要对应,个数要对应。
MethodTest03.divide(10, 2);
// 调用sum方法
// 怎么去接收这个方法的返回结果????
// 使用变量来接收这个方法的返回值。
// 注意:变量的定义需要指定变量的数据类型。
// 变量的数据类型是什么呢?
int jieGuo = MethodTest03.sum(100, 200);
System.out.println(jieGuo); //300
问题: jieGuo变量可以是double类型吗?
可以,double是大容量。int是小容量。自动类型转换。
double jieGuo2 = MethodTest03.sum(100, 200);
System.out.println(jieGuo2); //300.0
// 对于没有返回值(void)的方法,变量能接收吗?
divide方法结束没有返回值。不能接收。不能胡来。
// 错误: 不兼容的类型: void无法转换为int
//int i = MethodTest03.divide(100, 50);
// 当一个方法有返回值的时候,我可以选择不接收吗?
// 你可以返回值,但是我可以选择不要你这个值。这是允许的,只不过这样没有意义,一般程序返回了执行结果,都是需要接收这个结果的。就像计算器,你输入1+2,结果是3,你没看,但是你再不看,它还是输出了3这个结果。(没必要) 我们可以不接收,但是这个返回值该返回还是会返回的。只不过不用变量接收。
// 以下代码虽然没有使用变量接收这个返回值,但是这个值还是返回了。
// 返回之后内存马上释放,因为没有使用变量接收。
MethodTest03.sum(100, 200);
byte b1 = 10;
byte b2 = 20;
int result = sum(b1, b2);
// 这样就相当于b1直接赋值给a,b2直接赋值给b。(形参里的int a,int b)
// (b1,b2)是实参。自动类型转换。
System.out.println(result);
}
// 计算两个int类型数据的和
// 可以
public static void divide(int a, int b){
System.out.println(a / b); // 5
}
}
// 类1
类名什么时候可省?什么时候不可省?
// 类1:
public class MethodTest04{
public static void daYin3(){ // 类1的dayin3方法
System.out.println("动力节点-口口相传的Java黄埔军校!");
}
// 程序入口
public static void main(String[] args){
// 调用println()方法。
MethodTest04.daYin(); // 调用类1的daYin方法
MethodTest04.daYin2(); // 调用类1的daYin2方法
MethodTest04.daYin3(); // 调用类1的daYin3方法
// “类名. ”可以省略吗?
daYin();
daYin2();
daYin3();
// 第一次跨类调用。
// 像这种情况下:“类名.”就不能省略了。
MyClass.daYin(); // 明确:调用类2的daYin方法
}
public static void daYin(){ // 类1的daYin方法
System.out.println("hello world!");
}
public static void daYin2(){ // 类1的daYin2方法
System.out.println("hello world2!!!");
}
}
// 类2(要开始跨类了)
class MyClass{
public static void daYin(){ // 类2的daYin方法
System.out.println("打印1");
}
public static void daYin2(){ // 类2的daYin2方法
System.out.println("打印2");
}
public static void daYin3(){ // 类2的daYin3方法
System.out.println("打印3");
}
}
也就是说,当不需要跨类调用程序的时候,类名是可省的,当需要跨类调用函数的时候,类名必须带上!!
不只是main方法可以调用其它方法
public class MethodTest05{
public static void main(String[] args){
System.out.println("main begin");
m1(); // 调用m1方法
System.out.println("main over");
}
public static void m1(){
System.out.println("m1 begin");
// 调用程序不一定写到main方法中,不要把main方法特殊化,这个m1方法也可以调用程序
m2(); // 调用m2方法
System.out.println("m1 over");
}
public static void m2(){
System.out.println("m2 begin");
T.m3(); // m2方法可以调用T类的m3()方法
System.out.println("m2 over");
}
}
class T{ // 声明第二个类:T
public static void m3(){
System.out.println("m3 begin");
System.out.println("T's m3 method execute!");
System.out.println("m3 over");
}
}
// 别自乱阵脚:任何一个方法体当中的代码都是遵循自上而下的顺序依次逐行执行的。
break和return;有什么区别?
public class MethodTest06{
//main方法的返回值类型是void,表示没有返回值。
public static void main(String[] args){
for(int i = 0; i < 10; i++){
if(i == 5){
//break; // 如果用break的话那就终止for循环
return; // 如果用return的话就终止当前的方法,和break; 不是一个级别的。
//return 10; // 因为函数的返回值类型是void,所以如果写return 10;的话,编译器会报错:错误: 不兼容的类型: 意外的返回值
}
System.out.println("i = " + i);
}
System.out.println("Hello World!");
}
}
缺少返回语句
大家分析以下代码,编译器会报错吗?
public class MethodTest07{
public static int m(){
boolean flag = true;
if(flag){
return 1; // 只有flag是true时才会执行return;语句,不然没有return;了。
}
}
错误: 缺少返回语句
编译器不负责运行程序,只讲道理,对于编译器来说,编译器只知道flag变量是boolean类型,只是一个变量罢了,对于具体flag是ture还是false并不在意,编译器觉得,这么写程序会有极大可能导致程序无法执行,为了确保程序不出任何纰漏,编译器会警告你:缺少返回语句
那应该怎么修改这个程序呢?
第一种方案:带有else分支的可以保证一定会有一个分支执行。
public static int m(){
boolean flag = true;
if(flag){
return 1;
}else{
return 0;
}
}
第二种方案:该方案实际上是方案1的变形。
return语句一旦执行,所在的方法就会结束。
public static int m(){
boolean flag = true;
if(flag){
return 1;
}
return 0;
}
在同一个域当中,"return语句"下面不能再编写其它代码。编写之后编译报错。
eg:public static int m(){
boolean flag = true;
if(flag){
return 1;
System.out.println("hello1"); // 错误: 无法访问的语句(因为在return后面,即使第一个分支执行了也不能输出hello1.)
}
return 0;
System.out.println("hello3"); // 这样写可以
}
第三种方案:也可以这么写,利用三目运算符
public static int m(){
boolean flag = true;
return flag ? 1 : 0;
}
public class MethodTest07{
public static void main(String[] args){
int result = m(); // 调用m方法
System.out.println(result); // 1
int result1 = x(true); // 调用x方法
System.out.println("result1 = " + result1); // result1 = 1
int result2 = x(false); // 再次调用x方法
System.out.println("result2 = " + result2); // result2 = 0
}
public static int m(){
boolean flag = true;
return flag ? 1 : 0;
}
public static int x(boolean flag){
return flag ? 1 : 0;
}



