一、方法
1、方法的概念
將一個功能抽取出來,放在類中的大括號中,形參一個獨立的功能,當需要使用它時,直接調用它,這樣可以增強代碼的復用性(重復利用),並解決代碼冗余現象。
Java方法是語句的集合,它們在一起執行一個功能
- 方法是解決一類問題的步驟的有序組合
- 方法包含於類或對象中
- 方法在程序中被創建,在其他地方被引用
2、設計方法的原則
方法的本意是功能塊,就是實現某個功能的語句塊的集合。我們設計方法的時候,最好保持方法的原子性,就是一個方法只完成一個功能,這樣利於我們后期的擴展
3、方法的語法
【訪問修飾符】返回值類型 方法名(【參數類型 參數名1,參數類型 參數名2.....】){
方法體
}
詳解:
訪問修飾符:用於修飾這個方法的調用范文 目前默認public static
返回值類型:無返回值就寫void 或者 方法執行后返回的結果的數據類型,方法執行完之后會將結果返回
方法名:給方法起名,遵循標識符的規則
參數類型、參數名:它們是同時定義,方法在執行時未知的數據,需要在調用方法時進行傳遞值,參數類型表示這個參數的數據類型,參數名就是這個參數的名稱,這個參數名稱可以在方法體中使用
方法體:這個方法具有的功能(代碼塊)
定義一個方法
public static int add(int num1,int num2){
return num1+num2;
}
4、方法的分類
根據方法的參數不同,返回值不同,可以將方法分為四類:
1、無參無返回值方法
語法
public static void 方法名(){
方法體
}
2、無參有返回值方法
語法
public static void 返回值類型 方法名(){
方法體
}
/**
* 定義無參有返回值,需要先指定 這個返回值的數據類型
* 生成一個100以內的隨機整數
*/
public static int getRandomNum(){
System.out.println("生成隨機數");
int num = (int)(Math.random()*100);
return num; //注意 返回值類型 必須與定義的數據類型一致
}
public static void main(String[] args) {
//調用有返回值類型
//(返回值可以接受,也可以不接受,一般建議接受)
int n=getRandomNum();
System.out.println(n);
}
// 結果在n中
3、有參無返回值方法
語法:
public static void 方法名(參數列表){
方法體
}
情況一:當參數中是基本數據類型,將實參的值賦值給形參
public static void add(itn num){
num++;
System.out.println("方法中num的值:"+num);
}
調用方法:num的改變不會改變n的值,因為是兩個獨立的內存
int n = 10;
System.out.println(n);
add(n);
System.out.println("方法外面 實參的值:"+n);
結果輸出:
方法中num的值:11
方法外面實參的值:10
情況二:當參數的數據類型是引用數據類型
例如:數組
//方法的比對 參數的數組
public static void add(int [] arr){
arr[0]++;
System.out.println("方法中aar[0]="+aar[0]);
}
調用:
int [] array = {10,20};
add(array);//會調用 參數是數組的add方法
System.out.println("方法外面的arr【0】"+array[0]);
結果:
方法中arr[0]=11
方法外面的arr[0]=11
例如:類的調用
public static void addAge(Stdent studen){
//將學生的年齡 獲取 自加
int age = student.age;
age++;
// 在重新賦值
student.age=age;
}
調用:
Student student = new Student(); //age默認為 18
System.out.println("方法調用之前:"+student.age);//18
addAge(student);// 傳送的地址
System.out.println("方法外面 學生的年齡:"+student.age);
結果輸出: 方法調用之前: 18
方法外面 學生的年齡:19
/**
* 以上方法調用 的結論: 對於參數為引用數據類型,方法外面和方法內部公用同一塊內存,
* 也就是說 參數再傳遞時,將引用類型的地址賦值給 方法的形參
* 對於基本數據類型 ,方法的參數將 值的副本賦值給形參,這樣形參的改變
* 不會影響實參的值
* 原因: 引用數據類型在參數傳遞時 是地址 (JVM對於堆內存的大小不可控)
* 基本數據類型在參數傳遞時 是值
*
*/
情況三:當參數是String類型時,String是引用數據類型,但是在參數傳遞時,與基本類型一樣
public static void main(String[] args){
//參數是字符串
String uname = “李四”;
sayHello(uname);
System.out.println("我最后對:"+uname+"sayHello");
}
public static void sayHello(String name){
name= "張三";
System.out.println("我對"+name+"sayHello");
}
結果: 我對張三sayHello
我最后對李四sayHello
4、有參有返回值方法
語法:
public static 返回值類型 方法名(參數列表){
方法體
}
例如:
public static String sayHello(String name){
name="張三";
System.out.println("我對"+name+"sayHello");
return name ;
}
調用:
public static void main(String[] args) {
// 參數是字符串
String uname ="李四";
// 將返回值接收 ,這是 uname 才被改變 ,如果不接受,則不改變
uname = sayHello(uname);
System.out.println("我最后對"+uname+"sayHello");
}
結果:
我對張三sayHello
我最后對張三sayHello
5、方法的調用
如果方法體中需要一些位置的數據作為執行條件,那么這些數據可以作為參數
如果方法需要返回數據,在定義有返回值的方法,且需要明確返回值類型
方法調用兩種方式:
- 對象名 方法名(參數)
- 直接寫方法名調用,但必須是static修飾的
//獲取這個字符串的第一個字符
public void method1(String str){
//返回字符串的第一個字符
return str。charAt(0);
}
//調用方法
對象名.method1()
//調用靜態方法 (static修飾的)
String s = "abc";
char c = method1(s) //s將賦值給方法的形參 str 那么方法執行時str有值
// c就是方法調用后的返回值0
6、方法參數傳遞
1、方法的參數是基本數據類型,它傳遞的是值
//計算一個屬的平方
public int pow(int a){
a = a + 2;
return a * a;
}
main:
int num = 4;
int sum = pow(num);//賦值給a
System.out.println(num);//4
System.out.println(sum);//36
2、方法的參數是引用數據類型,它傳遞的是地址(除了String類型除外)
//參數 是數組類型
public static int pow(int [] arr){
arr[0]=arr[0]+2; //根據地址 改變數組的第一個元素值 arr[0]=4;
return arr[0]*arr[0]; // 4*4
}
調用
// 調用另一個pow
int [] array = {2,3};
int sum2 = pow(array) ; // array中存放數組的地址 ,將地址賦值給 arr形參
System.out.println(array[0]);// 4
System.out.println(sum2 ); // 16
7、方法的重載
在一個類中,存在相同的方法名的兩個級以上的方法,且它們的參數列表不同(參數類型不通風,參數個數不同,參數順序不同),不考慮參數名,不考慮返回值類型
一個類中不能存在完全相同的方法,它們是重復的方法。JVM編譯不通過
例如:
public int add(int a,int b){
return a+b;
}
//重載
public int add(long a,long b){
return (int)(a+b);
}
//與前兩個 不重載
public void add(int c,int d){
}
// 能與 方法1 ,2 構成重載
public void add(int a){
}
// 能與 方法1 ,2 構成重載
public void add(int a ,long b){
}
// 能與 方法1 ,2 構成重載
public void add(long a ,int b){
}
注意:方法名是否相同,參數列表是否相同(數據類型,參數個數,參數順序)
方法重載的規則
-
方法名稱必須相同
-
參數列表不同(類型,個數,順序等)
-
方法的返回類型可以相同也可以不相同
-
僅僅返回類型不同不足以成為方法的重載
實現理論:
方法名稱相同時,編譯器會根據調用方法的參數個數,參數類型等逐個匹配,以選擇對應的方法,如果匹配失敗,則編譯器報錯
在一個方法中可以調用另外一個方法
//在一個方法中可以調用另外一個方法,它們的執行順序是這樣的
public static void main(String[] args) {
System.out.println("這是main方法 的開始語句塊");
method1();
System.out.println("這是main方法 的結束語句塊");
}
public static void method1(){
System.out.println("這是method1 的開始語句塊");
//在一個方法中可以調用另外一個方法,它們的執行順序是這樣的
method2();
System.out.println("這是method1 的結束語句塊");
}
public static void method2(){
System.out.println("這是method2 的開始語句塊");
method3();
System.out.println("這是method2 的結束語句塊");
}
public static void method3(){
System.out.println("這是method3 的開始語句塊");
System.out.println("這是method3 的結束語句塊");
}
8、方法的遞歸調用
1、定義
在一個方法中,運行方法自身調用,這樣的調用稱為方法的遞歸調用,為了避免出現方法調用時出現死循環,遞歸調用中必須定義 方法結束調用的條件。
方法遞歸調用執行流程
public static void m3(int i){
if(i==5){
return ;
}
System.out.println("這是m3方法開始i :"+ i);
i++;
m3(i);
System.out.println("m3方法的結束 i:"+ i );
}
public static void main(String[] args) {
m3(0); //
}
例題:用戶輸入一個數字使用遞歸計算出這個數的階乘
//使用遞歸輸入一個數計算它的階乘
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個數");
int num=sc.nextInt();
int sum=f(num);
System.out.println(sum);
}
public static int f(int n){
if (n==1)
return 1;
return n*f(n-1);
}
以下是遞歸的練習題,有興趣的可以做做
練習1 : 一組序列 1 ,1, 2,3, 8...13,21,34,55,89,144 n, 第12個數 為多少?
練習2: 1, 3, 5, 7, 9, 11 . 問前10個數的和
練習3 :前5個階乘之和 例如 5!+4!+3!+...1!
練習4:定義一個函數,函數有一個整型參數n,
如果參數n為偶數時,調用函數求1/2+1/4+...+1/n,
如果參數n為奇數時,調用函數1/1+1/3+...+1/n
練習5、 1/1+1/2+2/3+3/5+5/8.。。。前8個數之和。