CodeGym /Java Blog /Toto sisi /方法聲明
John Squirrels
等級 41
San Francisco

方法聲明

在 Toto sisi 群組發布
你好!您已經知道如何使用字段和方法創建您自己的類。現在我們將詳述方法。
方法聲明 - 1
當然,我們已經在課程中不止一次這樣做過,但我們主要介紹了一般性知識。今天,我們將剖析方法,研究它們的構成、創建它們的各種方法以及如何管理它們。:) 我們走吧!

方法聲明

所有定義方法的代碼都稱為方法聲明。方法聲明的一般形式可以描述如下:

access modifier, return type, method name (parameter list) {
    // method body
}
作為例子,看一下類的各種方法的聲明Dog

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1.訪問修飾符

訪問修飾符總是首先指示。 該類的所有Dog方法都標有public修飾符。這意味著我們可以從任何其他類中調用它們:

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
如您所見,Dog類的方法很容易在Main類中訪問。由於public修飾符,這是可能的。在 Java 中,還有其他修飾符。它們並不都允許在其他類中使用方法。我們將在其他課程中討論它們。要記住的主要事情是修飾符負責什麼:一個方法是否可以在其他類中訪問:)

2.靜態關鍵字

其中一種Dog方法 ,main()用關鍵字static標記。它也是方法聲明的一部分,我們已經知道它的含義了。我們在課程開始給出的方法聲明模板中沒有提到它,因為它是可選的。如果指定,則它必須位於訪問修飾符之後。還記得在最近的課程中我們談到了靜態(類)變量嗎?當應用於方法時,this 關鍵字具有大致相同的含義。如果方法是靜態的,則可以在不引用類的特定對象的情況下使用它。事實上,你不需要一個Dog對象來運行靜態main()方法Dog班級。沒有一個它會運行得很好。如果這個方法不是靜態的,那麼我們首先需要創建一個對象才能運行它。

3.返回值

如果我們的方法應該返回一些東西,那麼我們指定返回值的類型。從 getter 的示例中可以明顯看出這一點getName()

public String getName() {
   return name;
}
它返回一個String對象。如果方法不返回任何內容,則使用關鍵字voidwoof()代替,如方法中所示:

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

同名方法

在某些情況下,我們需要幾種不同的方式來調用一個方法。為什麼不創造我們自己的人工智能?亞馬遜有 Alexa,蘋果有 Siri,那麼我們為什麼不應該有一個呢?:) 在電影鋼鐵俠中,托尼·斯塔克創造了他自己不可思議的人工智能賈維斯。讓我們向這位了不起的人物致敬,並以他的名字命名我們的 AI。:) 我們需要做的第一件事是教 Jarvis 向進入房間的人打招呼(如果這樣一個驚人的智慧竟然是不禮貌的,那就太奇怪了)。

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
控制台輸出: 晚上好,托尼·斯塔克。你好嗎? 非常好!賈維斯現在可以歡迎客人了。當然,更多的時候是他的主人托尼·斯塔克。可萬一他一個人不來呢!但是我們的sayHi()方法只接受一個參數。所以它只能迎接一個進入房間的人,而忽略另一個人。不太禮貌,同意嗎?:/ 在這種情況下,我們可以通過簡單地編寫 2 個同名但不同參數的方法來解決問題:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
這稱為方法重載。方法重載使我們的程序更加靈活,並適應各種工作方式。讓我們回顧一下它是如何工作的:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
控制台輸出: 晚上好,托尼·斯塔克。你好嗎?晚上好,托尼·斯塔克和美國隊長。你好嗎? 太好了,兩個版本都有效。:) 但是我們沒有解決問題!如果有三個客人怎麼辦?當然,我們可以sayHi()再次重載該方法,以便它接受三個來賓姓名。但可能有 4 或 5 個。一直到無窮大。有沒有更好的方法教 Jarvis 處理任意數量的名字,而不用重載該sayHi()方法一百萬次()?:/ 當然有!如果沒有,您認為 Java 會成為世界上最流行的編程語言嗎?;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
當 ( String... names ) 用作參數時,表示將向該方法傳遞一個 String 集合。我們不必事先指定會有多少,所以現在我們的方法更加靈活:

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
控制台輸出: 晚上好,托尼·斯塔克。你好嗎?晚上好,美國隊長。你好嗎?晚上好,黑寡婦。你好嗎?晚上好,綠巨人。你好嗎? 在方法內部,我們遍歷所有參數並顯示用名稱格式化的短語。這裡我們使用一個簡化的for-each循環(您之前已經看到過)。在這裡很完美,因為 ( String... names ) 符號實際上意味著編譯器將所有傳遞的參數放入一個數組中。因此,我們可以使用變量就像我們處理數組一樣,包括在循環中迭代它。另外,它可以處理任意數量的傳遞字符串!兩人、十人,甚至一千人——這種方法對任何數量的客人都適用。比為所有可能性重載方法更方便,你不覺得嗎?:) 這是方法重載的另一個例子。讓我們給賈維斯一個printInfoFromDatabase()方法。它將顯示有關數據庫中某個人的信息。如果數據庫表明某人是超級英雄或超級反派,我們將顯示該信息:

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
輸出: 勞拉·帕默。出生日期:1972 年 7 月 22 日。雙峰,華盛頓 Max Eisenhardt。身高:15.6 英尺。體重:189 磅。也被稱為 supervillain Magneto 所以,我們的方法的行為取決於我們傳遞給它的數據。這是另一個重點:參數的順序很重要! 假設我們的方法接受一個字符串和一個數字:

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
如果Person類的sayYourAge()方法將一個字符串和一個數字作為輸入,那麼這就是這些參數必須傳遞給方法的順​​序!如果我們以不同的順序傳遞它們,那麼編譯器將產生一個錯誤並且這個人將無法說出他的年齡。順便說一句,我們在上一課中介紹的構造函數也是方法!您還可以重載它們(即創建多個具有不同參數集的構造函數)並且傳遞參數的順序對它們來說也很重要。它們是真正的方法!:)

如何調用具有相似參數的方法

如您所知,null是 Java 中的關鍵字。了解這null既不是對像也不是數據類型非常重要。想像一下,我們有一個Person類和一個introduce()方法,它宣布了這個人的姓名和年齡。此外,年齡可以作為文本或數字傳遞。

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
我們已經熟悉重載,所以我們知道這兩種方法都將按它們應該的方式運行: 我的名字是 Alex。我今年二十一歲,我叫瑪麗。我的年齡是 32 但是如果我們null作為第二個參數而不是字符串或數字傳遞會發生什麼?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
我們會得到一個編譯錯誤!是什麼原因造成的,“歧義”到底是什麼?事實上,這一切都很簡單。問題是我們有兩個版本的方法:一個以 aString作為第二個參數,另一個以 anInteger作為第二個參數。但是 aString和 anInteger都可以是null!因為它們是引用類型,null所以是它們兩者的默認值。這就是為什麼在這種情況下編譯器無法確定它應該調用哪個版本的方法。這個問題的解決方案非常簡單。Null可以顯式轉換為特定的引用類型。 因此,當你調用一個方法時,你可以在括號中指出你想要的第二個參數的數據類型!編譯器將理解您的“提示”並調用正確的方法:

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
輸出: 帶有兩個字符串的方法!我叫維克多。我的年齡是 null 請注意,如果數字參數是原始類型int,而不是 Integer 引用類型的實例,則不會出現這樣的錯誤。

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
你能猜出為什麼嗎?如果您確實猜到了原因,那就太好了!:) 因為原語不能null。現在編譯器只有一個選擇,即用introduce()兩個字符串調用方法。這是每次調用該方法時將運行的方法版本。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION