Java 面向对象(四)类的成员 之 方法

一、方法

  1、什么是方法(method、函数)

    (1)方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程;

    (2)将功能封装为方法的目的是,可以实现代码重用,简化代码,解决代码冗余的现象;

    (3)Java 里的方法不能独立存在,所有的方法必须定义在类里;

  2、方法的声明

    方法的声明格式:

修饰符  返回值类型  方法名(参数类型 形参2,参数类型 形参2,...){

  方法体程序代码;

  return 返回值;

}

    (1)修饰符:public、缺省、private、protected 等;

    (2)返回值类型:① 没有返回值:void;② 有返回值,声明出返回值的类型,与方法体中“return 返回值” 搭配使用;

    (3)方法名:属于标识符,命名时遵循标识符命名规则和规范,“见名知意”。(采用小驼峰命名)

    (4)形参列表:可以包含零个、一个或多个参数。多个参数时,中间用 “,”隔开;

    (5)返回值:方法在执行完毕后返还给调用它的程序的数据;

    (6)方法体:方法功能的体现; 

 三要素:返回值类型;方法名称;参数列表;     

    定义方法的注意事项:

    •     方法必须定义在类中方法外面;
    •       方法定义的先后顺序无所谓;
    •       方法不能定义在另一个方法的里面,即不能产生嵌套包含关系
    •       如果方法有返回值,那么必须写上 “return 返回值;”,不能没有。
    •       返回值类型,必须要和 return 语句返回的类型相同,否则编译失败;
    •       不能在 return 后面写代码,return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码;
    •       对于一个 void 没有返回值的方法,不能写 return 后面的返回值,只能写 return 自己。
    •       对于 void 方法当中最后一行的 return 可以省略不写。
    •       一个方法当中可以有多个 return 语句,但是必须保证同时只有一个会被执行到,两个 return 不能连写。

  3、方法的分类:按照是否有形参及返回值

    

    (1)如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用 return 关键字来返回指定类型的变量或常量:“return 数据”。

    (2)如果方法没有返回值,则方法声明时,使用 void 来表示。通常,没有返回值的方法,就不需要使用 return。但是,如果使用的话,只能“return;”表示结束此方法的意思。

    Tips:其中,写在方法括号中的参数称为 形参,而在实际调用中的参数称为 实参

  4、return 关键字的使用

    (1)使用范围:使用在方法体中;

    (2)作用:① 结束方法;

           ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。

    (3)注意点:return关键字后面不可以声明执行语句。

  注意:方法的使用中,可以调用当前类的属性或方法,但是不能在方法中定义方法。

二、方法的调用

  1、方法的调用

    方法通过方法名被调用,且只有被调用才会执行。

        (1)如果本类中同级别方法调用:直接调用即可。

【变量 = 】 方法名(【实参列表】);

    (2)在其他类中的方法调用:

【变量 = 】 对象名.方法名(【实参列表】);

     注意

      ① 是否传入实参:看被调用的方法是否有形参;

      ② 是否接受返回值:看被调用的方法是否为 void,如果是  void,就不需要也不能接受;如果不是void,可以接受返回值。

  2、方法调用的过程分析

      

      

  3、调用方法的三种形式

    (1)直接调用:直接写方法名调用;

    (2) 赋值调用:调用方法,在方法前面定义变量,接收方法返回值 数据类型 变量名称 = 方法名称(参数);

    (3)输出语句调用:在输出语句中调用方法, System.out.println(方法名()) 。不能用输出语句调用 void 类型的方法。因为方法执行后没有结果,也就打印不出任何内容。

  4、方法的调用格式要与方法的声明格式对应

      (1)是否要加"对象":看是否在本类中,还是在其他类中

      (2)是否要接受返回值:看被调用方法是否是 void

      (3) 是否要传实参:看被调用方法是否有形参列表

  3、注意点

    (1)方法被调用一次,就会执行一次;

    (2)没有具体返回值的情况,返回值类型用关键字 void 表示,那么方法体可以不必使用 return 语句。如果使用,仅用来结束方法。

    (3)定义方法时,方法的结果应该返回给调用者,交由调用者处理;

    (4)方法中只能调用方法或属性,不可以在方法内部定义方法。

三、方法的重载(overLoad)

  1、重载

    两同一不同:同一个类中,同一个名字,参数列表不同。

    在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

  2、特点

    与权限访问修饰符、返回值类型、形参变量名、方法体都无关,只看参数列表,且参数列表必须不同。

    (参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。

  3、案例:

 1 public void getSum(int i,int j){
 2     System.out.println("1");
 3 }
 4 
 5 public void getSum(double d1,double d2){
 6     System.out.println("2");
 7 }
 8 
 9 public void getSum(String s ,int i){
10     System.out.println("3");
11 }
12 
13 public void getSum(int i,String s){
14     System.out.println("4");
15 }

四、可变形参的方法

  1、可变个数的形参

    JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。

  2、使用

//JDK 5.0以前: 采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] books);
//JDK5.0: 采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a ,String…books);

  3、说明

    (1)声明格式: 方法名(参数的类型名 ... 参数名);

    (2)可变参数:方法参数部分指定类型额参数个数是可变多个:0个,1个或多个;

    (3)可变个数形参的方法与同名的方法之间,彼此构成重载

    (4)可变参数方法的使用与方法参数部分使用数组的一致的,所以,在一个类中,二者不能共存;

    (5)方法的参数部分有可变形参,需要放在形参声明的最后

    (6)在一个方法的形参位置,最多只能声明一个可变个数形参

  4、案例:

 1     public void show(String s){
 2         System.out.println("show(String)");
 3     }
 4     
 5     public void show(String ... strs){
 6         System.out.println("show(String ... strs)");
 7         
 8         for(int i = 0;i < strs.length;i++){
 9             System.out.println(strs[i]);
10         }
11     }
12     //不能与上一个方法同时存在,不能与数组类型的方法同时存在
13 //    public void show(String[] strs){
14 //        
15 //    }
16     
17     //The variable argument type String of the method 
18     //show must be the last parameter
19 //    public void show(String ...strs,int i){
20 //        
21 //    }

    注意:对于这种可变参数的方法,其实也是用数组来处理的,等前面几个满足形参后,后面就全部属于可变参数,所以只能有一个,并且还需要放在最后。

五、方法参数的值传递机制

  1、形参与实参

    形参:方法声明时的参数,声明的小括号内的参数;

    实参:方法调用时实际传给形参的参数值;

  2、Java的实参值如何传入方法呢——值传递机制

    Java里方法的参数传递方式只有一种: 值传递即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

    形参是基本数据类型将实参基本数据类型变量的“数据值”传递给形参

    形参是引用数据类型: 将实参引用数据类型变量的“地址值”传递给形参

  3、基本数据类型的参数传递

      

  4、引用数据类型的参数传递

    (1)案例一

      

         

    (2)案例二

      

           

    (3)案例三

      

         

  5、扩展

    (1)案例一

 1 public class Test1 {
 2 
 3     public static void main(String[] args) {
 4         int a = 10;
 5         int b = 10;
 6         
 7         //需要在调用method方法之后,仅打印出a=100,b=200
 8         method2(a, b);
 9         
10         System.out.println(a);
11         System.out.println(b);
12         
13     }
14     
15     public static void method(int a, int b) {
16         a = a * 10;
17         b = b * 20;
18         
19         System.out.println(a);
20         System.out.println(b);
21         
22         System.exit(0);
23     }
24     
25     public static void method2(int a, int b) {
26         PrintStream printStream = new PrintStream(System.out) {  //对输出流进行重载
27             public void println(String x) {
28                 if ("a=10".equals(x)) {
29                     x = "a=100";
30                 } else if ("b=10".equals(x)) {
31                     x = "b = 200";
32                 }
33                 super.println(x);
34             }
35         };
36         System.setOut(printStream);
37     }
38 }

    (2)案例二

 1 public class Test2 {
 2 
 3     public static void main(String[] args) {
 4         int[] arr = new int[10];
 5         System.out.println(arr);//地址值,调用了 println(Object o),打印的是地址值;
 6         
 7         
 8         char[] arr1 = new char[10];
 9         System.out.println(arr1); //地址值?  
10         
11         char[] arr2 = new char[]{'a', 'b', 'c'};
12         System.out.println(arr2);  //abc  对于char数组,调用了println(char x[])方法,是对该char数组进行遍历
13     }
14 }

六、递归方法

  1、递归方法:一个方法体内调用它自身

  2、递归方法

    (1)方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制;

    (2)递归一定要向已知方法递归,否则这种递归就变成了无穷递归,类似于死循环。会报(Stack OverflowError【栈空间溢出】)

  3、案例

 1 // 例1:计算1-n之间所有自然数的和
 2 public int getSum(int n) {// 3
 3 
 4     if (n == 1) {
 5         return 1;
 6     } else {
 7         return n + getSum(n - 1);
 8     }
 9 
10 }
11 
12 // 例2:计算1-n之间所有自然数的乘积:n!
13 public int getSum1(int n) {
14 
15     if (n == 1) {
16         return 1;
17     } else {
18         return n * getSum1(n - 1);
19     }
20 
21 }
22 
23 //例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
24 //其中n是大于0的整数,求f(10)的值。
25 public int f(int n){
26     if(n == 0){
27         return 1;
28     }else if(n == 1){
29         return 4;
30     }else{
31         return 2*f(n - 1) + f(n - 2);
32     }
33 }

    经典案例:

      (1)斐波那契数列

      (2)汉诺塔问题

      (3)快速排序

原文地址:https://www.cnblogs.com/niujifei/p/13663887.html