9、方法
9.1 概念
可以重复利用的代码
9.2 格式
权限修饰符 静态修饰符 返回值类型 方法名(参数列表){
方法体;
return 返回值;
}
其中权限修饰符、静态修饰符和参数列表是可写可不写的。
1、权限修饰符
public(公共的)、protected(受保护的)、private(私有的)
2、静态修饰符
static
3、返回值类型
有返回值时,返回值类型可以是基本数据类型和引用数据类型;
没有返回值时,返回值类型写void,表示无。
4、方法名
标识符:见名知意,使用小驼峰命名规则:只用一个单词命名时,全部小写即可;如果有多个单词组成,则从第二个单词开始每个单词首字母大写,例:toString方法。
5、参数列表
即方法中需要用到的由调用方法者传入的值;
参数列表可以为空,也可以是一个或多个参数;
格式:
(数据类型1 参数名1 , 数据类型2 参数名2 ,……)
6、花括号{}表示的是当前方法的范围。
7、方法体
一行或者多行代码
8、return
return是关键字,可以通过return将方法执行的结果返回给调用者。
return语句一旦执行则当前方法结束。
当返回值类型为void时,不可以通过return返回数据,但可以通过“ return ; ”语句来结束方法
9、注意:
(1)方法的位置:类中方法外;
(2)方法只有调用的时候在执行,不调用则不执行。
调用方法:
没有返回值时,可直接调用:
方法名(参数列表);
有返回值时,需要将返回值赋值给变量
返回值数据类型 变量名 = 方法名(参数列表);
(3)实参和形参
实参:调用方法时,传入的有具体数据值的参数;
形参:方法在定义时,在参数列表中指定的参数;
形参和实参的数据类型不一定要完全一致。只要实参能自动提升为形参的类型,就可以正常传参。
10、案例:
(1)调用没有返回值的方法,打印五遍“Hello World ! ”。
public class test {
public static void main(String[] args) {
print();
}
public static void print(){
for (int i = 0; i < 5 ; i++) {
System.out.println("Hello World!");
}
}
}
(2)调用有返回值的方法,返回"Hello World!"。
public class test {
public static void main(String[] args) {
String print = print();
System.out.println(print);
}
public static String print(){
return "Hello World!";
}
}
(3)调用有参数有返回值的方法,指定两个整型数值返回两者之和。
public class test {
public static void main(String[] args) {
int sum = sum(2, 3);
System.out.println(sum);
}
public static int sum(int a,int b){
return a+b;
}
}
(4)实参形参
①基本数据类型
基本数据类型,本身存储的是数据值,当实参给形参传值时,也是传递的具体的数据值,而形参修改的是自己的数据值,不会影响实参的数据值
public class test {
public static void main(String[] args) {
int num1 = 2;
int num2 = 3;
System.out.println("调用方法前:");
System.out.println("num1的值为:" + num1 );
System.out.println("num2的值为:" + num2 );
int sum = sum(num1,num2);
System.out.println("调用方法后:");
System.out.println("num1的值为:" + num1 );
System.out.println("num2的值为:" + num2 );
System.out.println("调用sum方法得到的值为:" + sum);
}
public static int sum(int a,int b){
a = 3;
return a+b;
}
}
运行结果
调用方法前:
num1的值为:2
num2的值为:3
调用方法后:
num1的值为:2
num2的值为:3
调用sum方法得到的值为:6
②引用数据类型
引用数据类型,本身存储的是地址值,当实参给形参传值时,传的是地址值,形参的值的修改会导致实参随之发生改变(因为修改形参会根据地址值指向的堆内存的实际数值进行修改)。
public class test {
public static void main(String[] args) {
int[] nums = {1,2};
System.out.println("调用方法前:");
System.out.println("nums[0]的值为:" + nums[0] );
System.out.println("nums[1]的值为:" + nums[1] );
int sum = sum(nums);
System.out.println("调用方法后:");
System.out.println("nums[0]的值为:" + nums[0] );
System.out.println("nums[1]的值为:" + nums[1] );
System.out.println("调用sum方法得到的值为:" + sum);
}
public static int sum(int[] arr){
arr[0] = 3;
return arr[0] + arr[1];
}
}
运行结果
调用方法前:
nums[0]的值为:1
nums[1]的值为:2
调用方法后:
nums[0]的值为:3
nums[1]的值为:2
调用sum方法得到的值为:5
9.3 方法递归
1、概念:
方法自己调用自己
优点:代码简单
缺点:如果控制不好,可能会出现栈溢出异常(StackOverflowError)
2、案例
求5的阶乘(n的阶乘:n! = 1 * 2 * 3 * ······(n-1) * n)
public class test {
public static void main(String[] args) {
int num = 5;
int res = factorial(num);
System.out.println("5的阶乘为:" + res );
}
public static int factorial(int a){
if (a == 1 || a == 0){
return 1;
}else{
return a*factorial(a-1);
}
}
}
运行结果
5的阶乘为:120
9.4 方法重写
1、概念
父子类之间,当子类继承了父类的方法,但是发现该方法不能满足自己的功能需求,则可以在子类中重新实现该方法,即为方法的重写。
2、特点
重写前后的方法名和参数列表必须保持完全一致。
3、注意
(1)当子类重写了父类的方法,通过子类对象调用重写的方法,调用的是子类重写之后的方法;
(2)父类中私有的方法子类不能重写,但是子类中允许存在一个和该方法签名(方法名和参数列表)完全一致的普通方法。
4、五个原则(两小两等一大)
(1)两小
①父类中方法如果返回值为引用数据类型,则子类重写的方法返回值类型必须小于或者等于父类的返回值类型;
②父类中方法抛出了异常,则子类重写的方法抛出的异常必须小于或者等于父类方法抛出异常的类型。
(2)两等
①方法签名必须保持一致,即方法名和参数列表保持一致;
②如果父类中方法的返回值的类型为 “ void ” 或者基本数据类型时,则子类中重写的方法的返回值类型必须保持一致。
(3)一大
子类重写方法的权限修饰符必须大于或者等于父类中的权限修饰符。
9.5 方法重载
1、概念
定义多个方法,且方法名相同,参数列表不同即方法的重载。
2、构成重载的条件
(1)参数个数相同,数据类型不同;
如method(int a,int b)和method(char a,char b)
(2)参数个数不同,数据类型相同;
如method(int a , int b)和method(int a , int b , int c)
(3)数据类型顺序不同
如method(int a , char b)和method(char a , int b)
3、调用重载方法时,如何确定调用哪一个方法?
(1)实参的列表和哪个重载方法的形参列表最像,就调用哪一个方法;
(2)如果形参中没有和实参的参数列表完全一致的重载方法,则程序会尝试将是实参的数据类型进行自动类型转换来匹配。
public class test {
public static void main(String[] args) {
sum(1);//不会报错,可以正常调用,输出1.0
}
private static void sum(double d) {
System.out.println(d);
}
}
(3)无法根据实参列表确定到底调用哪一个方法时,程序编译时会报错。
4、方法重载和方法重写的区别:
方法重载:@Overload
(1)方法名相同但是参数列表不同;
(2)在同一个类中。
方法重写:@Override
(1)方法名和参数列表都相同;
(2)基于父子类的继承关系。
9.6 构造方法
1、作用
初始化属性值
2、格式
权限修饰符 方法名(参数列表){
初始化属性值
}
3、注意
(1)构造方法没有返回值,且方法名和类名一致;
(2)创建类对象时,调用无参构造方法形式为:new 类名();
(3)创建类对象时,调用有参构造方法形式为:new 类名(对应属性值);
(4)构造方法没有返回值部分,并非返回值为void;
(5)如果类中没有定义构造方法,则程序底层会自动生成一个无参构造;如果类中只定义了有参构造方法,没有定义无参构造,则程序底层不会再自动生成无参构造,调用该类只会显示有参构造方法。
9.7 静态方法
1、格式
权限修饰符 静态修饰符 返回值 方法名(参数列表){
方法体;
return 返回值;
}
2、注意
(1)静态方法是static修饰的;
(2)静态方法可以通过 “ 类名.静态方法名() ” 直接调用静态方法;
(3)静态方法不能直接调用非静态方法,可以先创建对再调用非静态方法;
(4)子类可以继承父类的静态方法,但是不能重写静态方法。