CodeGym /Java Blog /ランダム /メソッド宣言
John Squirrels
レベル 41
San Francisco

メソッド宣言

ランダム グループに公開済み
やあ!フィールドとメソッドを使用して独自のクラスを作成することについてはすでに知っています。次にメソッドについて説明します。
メソッド宣言 - 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. アクセス修飾子

アクセス修飾子は常に最初に示されます。 クラスのメソッドはすべてpublicDog修飾子でマークされています。これは、他のクラスからそれらを呼び出すことができることを意味します。

public class Main {

   public static void main(String[] args) {

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

}
ご覧のとおり、DogクラスのメソッドにはMainクラス内で簡単にアクセスできます。これはpublic修飾子により可能になります。Java には他にも修飾子があります。これらすべてが他のクラスでメソッドを使用できるわけではありません。それらについては他のレッスンでお話します。覚えておくべき主なことは、修飾子が何を担当するか、つまりメソッドが他のクラスでアクセスできるかどうかです:)

2. 静的キーワード

Dogメソッドの 1 つである にはmain()、キーワードstaticが付けられています。これはメソッド宣言の一部でもあり、その意味はすでにわかっています。これはオプションであるため、レッスンの最初に示したメソッド宣言テンプレートでは言及しませんでした。指定する場合は、アクセス修飾子の後に指定する必要があります。最近のレッスンで静的 (クラス) 変数について話したのを覚えていますか? このキーワードをメソッドに適用すると、ほぼ同じ意味になります。メソッドがstaticの場合、クラスの特定のオブジェクトへの参照なしで使用できます。Dogそして実際、静的main()メソッドを実行するためにオブジェクトは必要ありません。Dogクラス。何もなくても問題なく動作します。このメソッドが静的でない場合は、それを実行するためにまずオブジェクトを作成する必要があります。

3. 戻り値

メソッドが何かを返す必要がある場合は、戻り値の型を指定します。これはゲッターの例から明らかですgetName()

public String getName() {
   return name;
}
オブジェクトを返しますString。メソッドが何も返さない場合は、メソッドのようにキーワードvoid がwoof()代わりに使用されます。

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

同じ名前のメソッド

メソッドを呼び出すためにいくつかの異なる方法が必要になる場合があります。独自の人工知能を作成してみませんか? Amazon には Alexa があり、Apple には Siri があるのに、なぜ私たちがそれを持たないほうがいいのでしょうか? :) 映画『アイアンマン』では、トニー・スタークが独自の驚異的な人工知能、ジャービスを作成します。その素晴らしいキャラクターに敬意を表し、彼に敬意を表して AI に名前を付けましょう。:) 私たちが最初に行う必要があるのは、ジャービスに部屋に入ってくる人々に挨拶をするように教えることです(そのような驚くべき知性が失礼であることが判明した場合は奇妙です)。

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()メソッドは引数を 1 つだけ受け入れます。したがって、部屋に入ってくる 1 人だけを歓迎し、もう 1 人は無視します。あまり礼儀正しくないですね、同意されましたか?:/ この場合、同じ名前でパラメータが異なる 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");
   }
}
コンソール出力: こんばんは、トニー・スターク。元気ですか?こんばんは、トニー・スタークとキャプテン・アメリカ。元気ですか? 素晴らしいですね、両方のバージョンが機能しました。:) しかし、問題は解決しませんでした。ゲストが3人だったらどうしますか?もちろん、sayHi()メソッドを再度オーバーロードして、3 つのゲスト名を受け入れるようにすることもできます。しかし、4 つや 5 つある可能性もあり、無限に至るまであります。sayHi()メソッドを 100 万回もオーバーロードせずに、任意の数の名前を処理できるように Jarvis に教える、もっと良い方法はないでしょうか? :/ もちろんあります! もしそれがなかったら、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 ) がパラメーターとして使用される場合、文字列のコレクションがメソッドに渡されることを示します。事前にその数を指定する必要がないため、この方法はより柔軟になりました。

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 ) 表記は実際には、コンパイラーが渡されたすべての引数を配列に入れることを意味するため、これは完璧です。その結果、変数名を操作できるようになります。ループ内で配列を反復処理するなど、配列を操作する場合と同様です。さらに、渡された文字列の数に関係なく機能します。2 人、10 人、さらには 1,000 人でも、この方法はゲストの数に関係なく適切に機能します。すべての可能性を考慮してメソッドをオーバーロードするよりもはるかに便利だと思いませんか? :) これはメソッドのオーバーロードの別の例です。ジャービスに方法を教えてみましょう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 日。ツイン・ピークス、ワシントン州マックス・アイゼンハート。身長: 15.6 フィート、体重: 189 ポンド。スーパーヴィラン マグニートーとしても知られています 。したがって、メソッドの動作は、メソッドに渡すデータによって異なります。もう 1 つの重要な点があります。引数の順序が重要です。 私たちのメソッドが文字列と数値を取るとしましょう:

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);
   }
}
私たちはオーバーロードについてはすでによく知っているので、どちらのメソッドも正常に動作することがわかっています。 私の名前はアレックスです。私の年齢は21歳です。私の名前はメアリーです。私の年齢は 32 です。nullしかし、文字列や数値の代わりに 2 番目のパラメータとして 渡すとどうなるでしょうか?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
コンパイルエラーが発生します。これは何が原因で、「曖昧さ」とは一体何なのでしょうか? 実際、それはすべて非常に簡単です。問題は、メソッドに 2 つのバージョンがあることです。1 つはString2 番目の引数として a を持ち、もう 1 つはInteger2 番目の引数として an を持ちます。しかし、 aStringと an はIntegerどちらも可能ですnull。これらは参照型であるため、null両方のデフォルト値は です。そのため、この状況ではコンパイラーはメソッドのどのバージョンを呼び出す必要があるかを判断できません。この問題の解決策は非常に簡単です。Null特定の参照型に明示的に変換できます。 したがって、メソッドを呼び出すときに、2 番目の引数に必要なデータ型を括弧内に指定できます。コンパイラはあなたの「ヒント」を理解し、正しいメソッドを呼び出します。

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);
   }
}
出力: 2 つの文字列を含むメソッド! 私の名前はビクターです。私の年齢は null です。 数値パラメーターがintInteger 参照型のインスタンスではなくプリミティブであった場合、このようなエラーは発生しないことに注意してください。

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。ここで、コンパイラの選択肢は 1 つだけです。つまり、introduce()2 つの文字列を使用してメソッドを呼び出すことです。これは、メソッドが呼び出されるたびに実行されるメソッドのバージョンです。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION