ITエンジニアのプレイングマネージャー化応援サイト

8.クラスメソッド

この記事では、当社 の新人エンジニア研修の参考にJava8を解説します。

前回は文字と文字列の扱いについて解説しました。

クラスやインスタンスという言葉が出てきて、いよいよオブジェクト指向らしくなっていましたね。

今回はクラスメソッドについて解説します。

 

1.メソッドとは

プログラムが長くなると全体の見通しが悪くなることがあります。

プログラム全体で何をやっているのか分からなくなる訳です。

 

また、あちらこちらで同じコードを書いているときがあります。

そうすると無駄に記述量ばかり増えて、かつ、修正が必要になった際にはすべてのコードを修正しなければならなくなります。

DRY(Don’t Repeat Your Self:繰り返しを避けよ)原則とも呼ばれます。

 

そんな時は命令文を分けた方がプログラムを読んだ人にも分かりやすくなり、後々のメンテナンスも容易になります。

そのような時にメソッドを使います。

methodとは、直訳すれば「方法、やり方」といった意味です。

メソッドはJava以外の言語では関数と呼ばれることもあります。

関数と同様、xに何かを入れたらyが出てくるブラックボックスのようなものと捉えてください。

直線を表す

y = 2x + 1 

という関数のように。

 

一番シンプルなメソッドの形は、インプット(引数)、アウトプット(戻り値)ともになく、処理だけをするという、以下のようなものです。

void メソッド名() {

      命令文

}

メソッドの例として、10数える(1~10までの整数を表示する)という処理を持ったcount10()というメソッドを作成してみます。

<結果>

1
(中略)
10

mainメソッドについては、この連載の1回目でお話ししました。

プログラムのエントリーポイントでしたね。

mainメソッドでは、

count10();

とだけ書かれており、ここでメソッドを呼び出しています。

以降はメソッドの中に処理が移り、処理が終わるとメインメソッドに処理が戻ります。

ですから、count10メソッドとmainメソッドの位置関係を逆にして、以下のように書いても同じことです。

メソッドには、引数と戻り値があるのでした。

引数とは、メソッドに渡す値のことです。

戻り値とは、メソッドの呼び出し元(上記サンプルプログラムの場合はmainメソッド)に戻す命令を実行した結果の値のことです。

上記の例では、引数はなし、戻り値もvoidなので無しというわけです。

 

ここからは順に、引数や戻り値を使った例をご紹介します。

 

2.引数のあるメソッド

引数のあるメソッドは以下のような形をしています。

void メソッド名(型 変数名) {

      命令文

}

()カッコの中に型と変数名を書きます。

このメソッドのブロックの中では、この変数名を使って処理を記述することができるようになります。

先のサンプルプログラムに手を加えて、10まで数えあげるだけではなく、実引数で与えられた任意の数まで数えあげることができるようにしてみます。

<結果は省略>

 

3.戻り値のあるメソッド

戻り値のあるメソッドは以下のような形をしています。

戻り値の型 メソッド名(引数列) {

      命令文

  retrun 戻り値;

}

ポイントは、以下の3点です。

1.戻り値の型をメソッド名の前に書きます。

2.return文を使って戻り値を戻します。

3.最終的に戻すことができる値は1つだけです。

例として、一辺の長さを与えると正方形の面積を返すメソッドgetAreaOfSquereを作成してみましょう。

※なお、クラス名やメソッド名で単語の連なりを使いたい場合は、上記のように2つ目以降の単語の頭文字を大文字にします。
このような命名方法をラクダの形に見立ててキャメルケース(英: camel case)といいます。

結果

14.44

先ほど、

3.最終的に戻すことができる値は1つだけです。

と書きました。

この意味は、if文などの条件分岐でreturn文は複数あっても、最終的には戻り値は一つに決まるという意味です。

サンプルプログラムで確認してみます。

与えられた引数が偶数かどうかを判定するisEvenというメソッドです。

<結果>

false

なお、参考までに上記のプログラムは簡略化して以下のように書くこともできます。

static boolean isEven(int num) {
   return num % 2 == 0;
}

boolean型とはtrueかfalseのいずれかの値を持つものだからです。

 

4.メソッドのオーバーロード

ここまで学んできて、あれ?と思った方はいませんか?

例えば、次のサンプルプログラムを見てください。

おなじみのprintlnメソッドです。

渡している実引数の型はそれぞれ、String,char,int,doubleですね。

では、printlnメソッドの定義はどうなっているのでしょうか?

IDEをお使いの方はコントロールキーを押しながらprintlnメソッドをクリックしてみてください。

Javaのソースコードに飛びますが、4つのprintlnメソッドのうちのどれを押すかによって飛び先が違いますね。

例えば、doubleの場合は、

public void println(double x)

という定義に飛びます。

文字列の場合は、

public void println(String x)

です。

仮引数の型が違うだけですね。

このようにメソッド名と戻り値の型が同じで、引数の型や数、並び順が違うメソッドを複数定義することをオーバーロード(英:overload)といいます

日本語では多重定義と訳されます。

 

引数の型や数が違えば別のメソッド定義が必要となるわけですが、

もし、そのためだけに違ったメソッド名を用意しなければならないとすれば大変です。

メソッドを使う側も引数の型や数に気を付けて呼び出す必要が出てきてしまいますね。

しかし、オーバーロードによってそのような負担は無くなるのです。

皆さんも今までprintlnに渡す引数の型など、気にもしなかったのではないでしょうか?

 

そしてこの仕組みは皆さんも利用することができます。

サンプルプログラムを見てください。

結果

引数なしのmethodが呼ばれました。
int型の引数のmethodが呼ばれ2を受け取りました。
double型の引数のmethodが呼ばれ3.14を受け取りました。
文字列の引数のmethodが呼ばれGoodby.を受け取りました。

オーバーロードとは、同じクラスの中でメソッド名と戻り値の型が同じで、

引数の型や数、並び順が違うメソッドを複数定義することをいいましたね。

呼び出し時に指定される引数によって実行されるメソッドが区別されるという仕組みでした。

注意点としては、戻り値の型が違っても、それだけではオーバーロードにならないという点です。

①メソッド名、②引数の型、③引数の数の3つの要素をシグネチャと呼びます。

オーバーロードは、①が同じで、②または③が異なる場合と引数の並び順が違う場合に有効なのでした。

なお、シグネチャが全く同じメソッドを複数宣言することはできません。

 

5.メソッドを使うことでメッセージ性が高まる

定型の処理の再利用のほかにもメソッドを使うメリットがあります。

それは、メソッドを使うことでメッセージ性が高まるというものです。

例えば、

if (age >= 20){

    system.out.println(“酒を飲む”);

}

というコードがあった時に以下のようにisAdultというメソッドを使えば、成人判定をしているということがより分かりやすくなりますね。

 

では、メソッドを使うことのデメリットは何でしょうか?

それは、プログラムを上から順に追えなくなることです。

これまでのサンプルプログラムでは、上から順にみていけばプログラムを読み解けました。

これをアルゴリズムでは順次と呼んでいましたね。

しかし、ここからは処理があちらこちらに飛ぶので慣れないうちは大変かもしれません。
※もっとも処理が別クラスに分かれて、クラス同士が引数と戻り値をやり取りするようになると、ますます複雑になるのですが。。。

特に次の再帰処理などは初学者が理解困難な部分です。

しかし、理解できればメソッドの動きはよく理解できるようになりますので説明してみましょう。

 

6.メソッドの再帰処理

では、ここで実験をしてみましょう。

以下のコードはどのような結果になるか予想してください。

メインメソッドの中でメインメソッドを呼んでいます。

呼ばれたメインメソッドの中でもさらに次のメインメソッドを呼び出して延々終わりません。

このようにあるメソッドの中で自分自身のメソッドを呼び出すことを再帰処理といいます。

ただし今回の場合は、エラーを出してプログラムは終了してしまいます。

<結果>

Exception in thread “main” java.lang.StackOverflowError
at chap08.Example9.main(Example9.java:6)

(中略)

Stack(スタックを)Overflow(溢れ出した)Error(エラー)ということですね。

ここでは、エラーという表現を心の片隅に置いておいてください。

また、例外処理というところでお話ししたいと思います。

 

ここで理解していただきたいのはメモリのスタック領域というところにメソッドが積み上げられていくということです。

メソッド(やローカル変数)はスタック領域に保存されるのです。

データ構造のところで学んだかもしれませんが、スタック(英:stack)は積み上げという意味です。

先入れ後出しのデータ構造です。

図解すれば以下のようなイメージでメモリのスタック領域が上へ上へと積まれたメインメソッドで覆いつくされてしまったのです。

メソッドがこのように古いものから新しいものへどんどん積み重ねられるというイメージを持つようにしてください。

 

新人の型で再帰処理が理解できない人は多いです。

その理由は、ソースコードが動くと思っているからです。

実は皆さんが書いたソースコードは動きません。

ソースコードがメモリに展開されて動いているのです。

つまり、上記のスタック領域の図です。

このことが分かれば躓かないと思いますので、しっかり理解しましょう。

 

7.メソッドチェーン

メソッドの戻り値に対してメソッドをつなげていく書き方を今後目にすることがあると思います。

メソッドチェーン(method chain)といいます。

具体例を見ましょう。

以下のサンプルプログラムでは、文字列”hello”を大文字にしたうえでその先頭文字を取り出してコンソール出力しています。

<結果>

 

左から順に処理されて、

“hello”.toUpperCase()

によって、戻り値の”HELLO”を得、

“HELLO”.charAt(0)

によって、戻り値の”H”を得ています。

メソッドチェーンは、あまり多用すると読みにくいコードになるので注意が必要ですが、便利な書き方なのでしばし使われます。

 

 

ここまで理解できたら以下の練習問題を解いてみましょう。

 

6.クラスメソッド

 

今回はクラスメソッドについて見てきました。

クラスメソッドにはstaticキーワードがついていました。

staticは静的という意味で、staticメンバはプログラムの実行開始前にあらかじめメモリー上にコピーされるという意味です。

一方、インスタンスはプロジェクトの実行中に必要な時に必要なだけ作られるというのが大きな特徴です。

つまり必要な時になって初めてメモリーにコピーするのです。

これを動的(dynamic)に作るということもあります。

次回のテーマはインスタンスの活用です。

いよいよ、オブジェクト指向らしいプログラムになってきます。

クラスを元にインスタンスを作成してそれぞれのインスタンスのメソッドを使う方法について学びましょう。

 

JavaSE8の解説に戻る

新入社員研修ポータル

IT企業の人財育成に関することなら全てお任せ下さい TEL 0120-559-463 受付時間 10:00 - 17:00 (土・日・祝日除く)

ZOOMを使った遠隔研修メニュー(PDFが開きます)

ZOOMを使った遠隔研修

新人エンジニアのためのJavaタイピングゲーム

新人プログラマのためのプログラミング動画

YouTubeチャンネル

お問い合わせはこちらから

    お名前 (必須)

    メールアドレス (必須)

    題名(件名)

    メッセージ本文

    確認画面は表示されません。上記内容にて送信しますので、よろしければチェックを入れてください。

    新入社員研修ポータル

    PAGETOP
    Copyright © Say Consulting Group, Inc. All Rights Reserved.