Java程序的方法設計

Java程序的方法設計

本文關鍵字:Java、方法定義、方法設計、方法調用、方法重載java

1、方法的定義

咱們在學習Java編程之後接觸到的第一個程序就是"Hello World」,在這當中涉及到兩個主要的結構:類和main方法,當時咱們只是說明了main方法是程序的入口,那麼當咱們想要本身定義一個方法時應該如何下手呢?編程

1. 概念與做用

首先咱們要明確方法的概念和做用,從名稱上來講,方法也能夠被稱爲函數,是用來解決同一類的問題的。從代碼的結構上來講,定義方法能夠減小重複的代碼,也能使得整個程序結構更加清爽。數組

  • 假如咱們須要計算兩個數的加和
public class Test{
    public static void main(String[] args){
        // 定義兩個變量,so easy
        int a = 10,b = 5;
        int c = a + b;
        System.out.println(c);// 15
    }
}
  • 若是咱們須要屢次反覆執行同一個邏輯,那麼就會產生不少相同的代碼
public class Test{
    public static void main(String[] args){
        int a = 10,b = 5;
        int c = 20,d = 10;
        // 能夠看到,雖然變量名稱不一樣,可是計算的邏輯是相同的
        // 若是某一段代碼反覆出現,咱們能夠考慮將他提取出來變成一個方法
        int e = a + b;
        System.out.println(e);// 15
        int f = c + d;
        System.out.println(f);// 30
        int g = e + f;
        System.out.println(g);// 45
    }
}
  • 定義方法後調用
public class Test{
    public static void main(String[] args){
        int a = 10,b = 5;
        int c = 20,d = 10;
        // 原有的代碼邏輯將轉變爲方法的調用
        plus(a,b);// 執行方法時輸出:15
        plus(c,d);// 執行方法時輸出:30
        plus(e,f);// 執行方法時輸出:45
    }
    // 定義一個用於計算兩個數加和的方法,計算後輸出結果
    public static void plus(int m,int n){
        int result = m + n;
        System.out.println(result);
    }
}

從以上的例子咱們能夠看到:jvm

  • 從結構上來講,方法就是由多行代碼所組成的集合
  • 從使用的角度來看,定義方法的目的是抽取出通用的部分,能夠減小重複代碼的出現
  • 從最終的效果來看,多行代碼的執行轉化爲了方法的調用

2. 定義的格式

若是咱們想定義一個方法,那就須要先了解定義方法的結構,按照次序分別爲:ide

  • 修飾符:對方法進行相關的限定,出如今返回值類型以前
    • 權限修飾符:通常咱們會將權限修飾符寫在方法定義的最前面,它指明瞭這個方法均可以在什麼地方被調用,最開始都聲明爲public便可
    • 其餘修飾符:能夠修飾方法的關鍵詞還有static,final等,會在其餘文章中逐一介紹,修飾符的前後順序沒有嚴格要求
  • 返回值類型:指明瞭方法執行後是否須要進行返回,以及相應的類型
  • 方法名:指定方法的名稱,方法被調用時使用,在同一類中同名方法將構成重載
  • 參數列表:聲明調用方法時須要傳入的參數,能夠爲空,也能夠多個
  • 方法體:方法被調用時所執行的代碼,是方法的核心部分,須要與方法的返回值類型呼應

3. 方法的簽名

方法名稱和參數列表構成了方法簽名,方法簽名能夠惟一的肯定一個方法,而且對鑑別是否構成重載十分有用。函數

public class Test{
    // 方法簽名:main(String[] args)
    public static void main(String[] args){
        int a = 10,b = 5;
        int c = plus(a,b);
    }
    // 方法簽名:plus(int m,int n)
    public static int plus(int m,int n){
        return m + n;
    }
}

4. 方法的註釋

在定義一個方法後,咱們在使用編譯器調用時只可以查看到方法簽名及返回值類型,咱們但願對於相近或重載的方法進一步進行描述,有利於使用者對方法的區分。
對方法添加註釋時須要使用文檔註釋,稱之爲javadoc,這樣在進行調用時就能夠顯示方法的相關信息,對於方法的註釋主要包括如下幾個部分:學習

  • 方法做用描述:描述方法的做用
  • 方法參數描述:@param,解釋每一個參數表明的含義
  • 返回類型描述:@return,解釋返回值表明的含義

在編譯器中能夠輸入/**快速生成一個方法的模板,效果以下:spa

public class Test{
    /**
     * 計算兩個數的加和
     * @param a 第一個加數
     * @param b 第二個加數
     * @return 兩個數的加和
     */
    public int plus(int a,int b){
        return a + b;
    }
}

2、方法的設計

明確了方法的定義結構以後,咱們須要作的就是但願在解決實際問題時知道如何去定義一個方法,而且有一個清晰的思路。翻譯

1. 方法設計的思路

筆者認爲一個方法的設計其實更像是整個編程思想的縮影,不管是完成一個複雜的功能仍是某一個方法的定義均可以按照下面三個步驟來進行:設計

  • What I want?

要定義一個方法,就要先明確:我須要完成怎樣一個功能,用於解決一個什麼樣的問題?明確了以後咱們就能夠知道這個方法的用途,進而肯定方法的名稱、返回值類型、調用訪問的權限、是否有其餘修飾符。

  • What I need?

接下來要咱們要根據方法的用途,考慮這個方法執行時都須要什麼,是否須要傳入一些參數?因而咱們能夠肯定參數列表的部分了。

  • How to do?

在明確了方法要解決的問題以及所須要的參數以後,咱們就能夠分析方法中用該編寫什麼樣的代碼來解決問題,也就是最後肯定方法體的部分,用上傳遞進來的參數,最後返回應該返回的變量或進行打印輸出。

2. 方法名稱的肯定

方法名稱的定義比較容易,由於自定義的程度較高,沒有什麼強制性的規則,只要知足標識符的規定就能夠了。通常來講,方法的命名也須要作到見名知意,以小寫字母開頭,若是遇到多個單詞首字母大寫,能夠是字母和數字的組合。

3. 參數列表的肯定

參數列表的肯定主要就是考慮調用方法時須要傳入的參數的類型,能夠爲空,也能夠爲一個至多個,分別須要聲明類型和名稱。

  • 聲明的類型用於限制調用方法時傳入參數的類型
  • 聲明的名稱用於表明傳遞進來的參數

除此以外,咱們還須要瞭解一下各類參數類型之間的差異:

  • 基本數據類型:對於基本數據類型,咱們能夠認爲是值的傳遞,即:這是一個值拷貝以後,複製的過程,咱們在方法中若是對參數的值進行修改,也不會改變原有的值。
public class Test{
    public static void main(String[] args){
        int a = 10;
        test(a);// 進行方法的調用,方法中對值進行了修改
        System.out.println(a);// 結果爲10
    }
    public static void test(int n){
        System.out.println(n);// 接收到值,結果爲10
        n = 100;// 修改n的值,不會影響傳入的參數a的值
        System.out.println(n);// 結果爲100
    }
}
  • 引用類型:包括數組在內的引用類型,也就是除了基本數據類型之外的其餘類型,在進行傳遞時發生的是引用傳遞,也就是說參數接收到的是一個引用,至關於多了一個變量指向了同一個位置,這樣在方法中進行的修改直接會做用在對象實例上。
public class Test{
    public static void main(String[] args){
        int[] a = {1,2,3};
        test(a);// 進行方法的調用,方法中對數組a進行了修改
        for(int i = 0;i < a.length;i++){
            System.out.println(n);// 結果爲10,20,30
        }
    }
    public static void test(int[] n){
        for(int i = 0;i < n.length;i++){
            System.out.println(n[i]);// 接收數組的引用,結果爲:1,2,3
        }
        for(int i = 0;i < n.length;i++){
            n[i] = n[i] * 10;// 修改數組的值,每一個元素變爲原來的10倍
        }
        // 對於修改對象的屬性值同理,直接做用在對象自己
    }
}

Java程序的方法設計

  • 可變參數:可變參數與數組相似,可是卻有所不一樣,容許調用時以羅列的方式將參數傳進來
    • 可變參數又叫不定參數,從字面解釋就是:有的時候我不肯定參數到底有幾個,可是又不想每次都構建一個數組,這個時候就可使用不定參數
    • 可變參數在一個方法的定義中只能出現一個
    • 可變參數只能出如今參數列表的最後一個位置
    • 不建議使用Object類型做爲可變參數類型,將在方法重載時說明
    • 聲明格式:參數類型... 參數名稱,如:int... nums
public class Test{
    public static void main(String[] args){
        int a = 1;
        int b = 2;
        int c = 3;
        test(null);// 調用成功,此時參數爲null
        test();// 調用成功,此時參數個數爲0
        test(a);// 調用成功,傳入1個參數
        test(a,b);// 調用成功,傳入2個參數
        test(new int[]{a,b,c});// 調用成功,也可構建成數組後傳入
    }
    public static void test(int... nums){
        // 將nums當成數組同樣使用便可,能夠經過判斷數組長度肯定傳入參數的個數
        // 前提是傳入的參數不爲null,不然會出現空指針異常
        if(nums == null){
            System.out.println("傳入的參數爲null");
        }else{
            System.out.println("傳入的參數個數爲:" + nums.length);
        }
    }
}

4. 返回類型的肯定

如何肯定一個方法是否須要有返回值呢?在上述的方法中,在返回值類型的部分咱們使用的都是void關鍵字,表明此方法返回值爲空,或無需返回。其實,對於一個方法是否須要返回這不是一個語法問題,而是取決於咱們使用者的須要,咱們來討論一下這兩種狀況。

  • void:表明方法執行後不須要指定返回值,也就是不須要使用return關鍵字,只須要完成方法的邏輯,輸出某些信息,或者經過引用修改對象的某些屬性。
  • 其餘類型
    • 返回值類型只能指定一種,但能夠是數組類型
    • 若是聲明瞭返回值類型,那麼必須配合return關鍵字一同使用
    • return在通常狀況下只能出如今方法的最後一行,做爲方法的結束
    • 在選擇結構中,也可能不會出如今最後一行的位置,能夠根據須要提早結束某一個方法,可是必須保證選擇結構對應的全部狀況都有相應的返回值
    • return後只能跟一個變量的名稱或表達式,變量或表達式結果的類型必須和返回值類型相同
    • 若是須要同時返回多個變量的值,可使用數組
    • 若是須要同時返回多種類型的變量,能夠將返回值類型聲明爲:Object[]
public class Test{
    public static void main(String[] args){
        // 須要實現以下邏輯:計算兩個數的加和,並將獲得的結果變爲10倍後輸出
        int a = 1,b = 2;
        // 在進行方法調用後,咱們必須想辦法先獲得兩個數計算加和的結果,再繼續下一步
        int c = plus(a,b);
        // 使用對應類型的變量(c)接收返回結果,而後繼續下一步操做
        int result = c * 10;
        System.out.println(result);
    }
    public static int plus(int a,int b){
        return a + b;
    }
}

5. 方法內容的肯定

可以根據須要熟練並快速的寫出方法體中的內容這是一個長期訓練和鍛鍊的過程,有的時候咱們並非不知道如何使用方法這種結構,而是給出的問題根本沒有任何的思路。在這裏筆者將給你們一些建議,由於舉再多的例子也沒法在短期內對你們有實質性的幫助。
其實程序自己只是咱們一種邏輯思惟表達,並且計算機真的很笨,全部的步驟都須要你一步一步去告訴他,好比你想寫一個判斷素數的程序,不要期望你定義一個變量i,而後使用選擇結構在判斷條件中寫上:if(i == 素數){}計算機就能明白,你首先要讓計算機明白什麼是素數,或者符合什麼樣的條件的數是素數。基本上全部的問題均可以轉換爲一個數學問題,或者是具備步驟的邏輯問題,特別是咱們要讓計算機幫助咱們去完成一項操做或功能的時候,你必須告訴它明確的步驟,以及遇到各類狀況要如何處理,畢竟大佬是這麼說的:
Java程序的方法設計
不少同窗看到這句話的第一反應多是:我信你個鬼!你個xx頭子壞得很!可是仔細想一想其實頗有道理,特別是對於初學者,咱們在學習編程時必定要嘗試去理解計算機是如何工做的,如何教會它來幫助咱們解決問題。
那麼筆者的建議能夠歸納爲如下幾點:

  • 不要着急開始一個方法的編寫
  • 首先理清問題的解決步驟
  • 若是可能,對每個步驟進行細化,分析可能出現的狀況,給出解決的辦法
  • 結合所學的語法知識,將每個步驟翻譯爲相應的結構或代碼
  • 若是沒有解決問題,重複以上步驟
  • 經歷幾回以後你就能夠徹底在大腦中完成這幾個步驟,順暢的寫出方法的內容

3、方法的調用

當一個方法被定義之後,只有被調用了纔會被執行,不然也是沒有意義的。

1. 方法調用的格式

根據上面的例子,我想對於方法的調用方式你們已經掌握了。沒錯,很簡單:方法名稱 + 傳入參數。有關於參數的寫法上須要做出一點說明,在進行方法定義時,咱們須要聲明參數的類型,而在調用方法,傳入參數時,咱們須要作的僅僅是匹配,不要再次聲明參數的類型,而只須要保證傳入的參數與定義的類型相匹配就好,能夠傳入一個具體的值,也能夠是聲明賦值後的變量,仍是那句話:類型匹配就好。

2. 方法的執行過程

方法的執行過程其實比較簡單,具體的包含嵌套調用的結構咱們將在後面的文章中說明。方法的執行過程其實用到的了一個最基本的結構:順序結構。若是一段代碼在執行的過程當中遇到了方法調用,那麼必定會進入到方法中,將方法中的代碼所有執行完畢,再返回到方法的調用處,繼續執行後面的代碼。
那麼這裏也給你們解釋一下初學者的問題:你說方法中定義的return是返回的意思,那到底返回到哪去了?何時返回的?
解釋這個問題能夠用一句話歸納:返回到了調用該方法的位置。首先,只有一個方法被調用之後,纔會執行其中的代碼,纔會輪到return語句的執行,那麼return以後去哪了呢?天然是返回到調用這個方法的位置繼續執行,這個時候,整個方法的調用語句就表明了這個方法的返回值,咱們直接使用對應類型的變量接收就能夠了。

public class Test{
    public static void main(String[] args){
        // 須要實現以下邏輯:計算兩個數的加和,並將獲得的結果變爲10倍後輸出
        int a = 1,b = 2;// 代碼執行步驟:1
        // 代碼執行步驟:2,進行方法的調用
        int c = plus(a,b);// 代碼執行步驟:4,進行返回值的賦值
        int result = c * 10;// 代碼執行步驟:5
        System.out.println(result);// 代碼執行步驟:6
    }
    public static int plus(int a,int b){
        return a + b;// 代碼執行步驟:3
    }
}

3. 調用的注意事項

  • static修飾符

static修飾符有不少做用,咱們這裏只討論它用在方法上時,對方法的調用產生怎樣的影響。因爲main方法是程序的入口,那麼它必須使用static聲明,即:不須要實例化對象便可直接執行。那麼因爲main方法是static修飾的,那麼它直接調用的方法必須也是由靜態(static)修飾的。

  • 接收返回值

具備返回值的方法在調用後,是否是必定要對返回值進行接收呢?固然不是必須的,若是不接收,方法的值也會正常返回,只不過隨即被丟棄了而已。接收時將方法調用語句當作一個總體,直接用對應類型的變量賦值接收便可。

4、方法的重載

<span id="jump"></span>

1. 重載的概念

重載指的是在一個類中,能夠定義多個同名的方法,區別在於參數列表不一樣。對於重載的概念仍是很好理解的,無非是描述了一種現象,在一個類中存在了不少名字相同的方法,你們須要掌握的就是如何定義才符合重載的規則,以及重載有什麼用?

  • 方法名稱相同,參數列表不一樣

不要看這個概念簡單,仍是有不少同窗在此翻車。方法名稱相同很好理解,徹底一致的才叫作相同,這裏對大小寫敏感。另一個概念是:參數列表不一樣,你們必定要注意,參數列表相同與否,是靠參數類型以及排列順序來決定的,與參數名稱無關。由於參數列表中聲明的參數名稱只是傳入參數的一個表明,並不具有什麼具體的區分意義。

public class Test{
    // 求兩個整數和的方法:plus
    public int plus(int a,int b){
        return a + b;
    }
    // 參數列表相同,不構成重載,不能在類中同時存在
    public int plus(int c,int d){
        return c + d;
    }
    // 參數列表不一樣,構成重載
    public double plus(double a,double b){
        return a + b;
    }
    // 參數列表不一樣,構成重載,可是不定參數容易構成調用的歧義,不推薦
    public int plus(int... a){
        return 0;
    }
    // 參數列表相同,方法名稱不一樣,不構成重載,能夠在類中同時存在
    public int Plus(int a,int b){
        return a + b;
    }
}
  • 方法重載有什麼用?

在不少時候,咱們使用方法完成一個功能或邏輯,存在不少種狀況,有些狀況來自於代碼邏輯處理的過程當中,也有些狀況是要對不一樣的參數類型作出不一樣的操做。這個時候咱們就能夠利用重載的特色,用相同的方法名錶明咱們要處理的邏輯是相似的,而後在參數列表中聲明不一樣的參數類型,這樣就能夠避免咱們在方法中再繁雜的寫各類參數個數的判斷,參數類型的判斷,更加利於維護。同時,使用相同的方法類型,也使得使用者在調用時變得十分方便,不須要在同一功能上記憶各類不一樣的方法名稱,同時又能很好的解決問題。

2. 重載方法的調用

對於重載方法的調用,因爲方法名稱相同,jvm主要就是根據傳入的參數類型來進行區分,效果以下:

public class Test{
    public static void main(String[] args){
        int a = 1,b = 2;
        int c = plus(a,b);// 調用plus(int a,int b)
        double m = 1.0,n = 2.0;
        double d = plus(m,n);// 調用plus(double a,double b)
    }
    // 求兩個整數和的方法:plus
    public static int plus(int a,int b){
        return a + b;
    }
    // 方法名相同,參數列表不一樣,構成重載
    public static double plus(double a,double b){
        return a + b;
    }
}

從上面的例子咱們能夠看到,在執行方法調用時主要是經過參數類型來進行區分的。可是當方法中出現不定參數時要尤其注意:

public class Test{
    public static void main(String[] args){
        int a = 1,b = 2,c = 3;
        int d = plus(a);// 編譯失敗,與plus(int... a)和plus(int a,int... b)都匹配
        int e = plus(a,b);// 編譯成功,調用plus(int a,int b)
        int f = plus(a,b,c);// 編譯失敗,與plus(int... a)和plus(int a,int... b)都匹配
        int g = plus(new int[]{a,b});// 編譯成功,調用plus(int... a)
        int h = plus(a,new int[]{b,c});// 編譯成功,調用plus(int a,int... b)
    }
    // 求兩個整數和的方法:plus
    public static int plus(int a,int b){
        return a + b;
    }
    // 方法名稱相同,參數列表不一樣,構成重載,可是不定參數容易構成調用的歧義,不推薦
    public int plus(int... a){
        return 0;
    }
    // 方法名稱相同,參數列表不一樣,構成重載,可是不定參數容易構成調用的歧義,不推薦
    public int plus(int a,int... b){
        return 0;
    }
}

從以上的例子咱們能夠看到,若是重載方法中出現了不定參數,那麼在調用時極可能出現歧義,依然要經過手動構建數組的方式來解決,因此在進行方法重載時應該儘可能避免出現不定參數,當不定參數是Object類型時,歧義問題就會更加嚴重

相關文章
相關標籤/搜索