コード、ドキュメントが含まれています。印刷を御希望の方はページ一番下の「印刷用ページ」より印刷してください。PDFファイルとして保存したい場合も「印刷用ページ」より保存できます。見出しに「★」マークがついた箇所は説明動画がございます。継承とオーバーライド★講義のポイント【動画】講義のポイント※画面右下のアイコンをクリックすると全画面表示になります今回の講義では、ループ・配列・クラスと継承というAndroidアプリケーションを作成する際に欠かせない、Java言語とオブジェクト指向プログラミングの基礎を学習します。※画面右下のアイコンをクリックすると全画面表示になりますプロジェクトの作成eclipseを起動して、新規に「Loop」というプロジェクトを作成します。以下の情報にあわせて、各項目を入力して下さい。>」ボタンをクリックしてください。>」ボタンをクリックしてください。>」ボタンをクリックしてください。Noneまっさらな状態でアプリを実行し、エラーがでないことを確認します。World!」と表示されていればOKです。前回までの講義では、条件によって異なる処理を実行する、if文やswitch文を勉強しました。様々な処理を何度も繰り返して行いたい場合、どうすれば良いのでしょうか?ほぼ全てのプログラミング言語では、このような処理を、繰り返し文(ループ文)を利用することで記述することができます。言語によって繰り返し文の記述法は様々ですが、Javaではfor文、while文、do-while文の3つの繰り返し文が用意されています。do-while文を利用する機会は少ないため、まずはfor文とwhile文について学習しましょう。頻繁に用いるfor文について説明します。for文は、以下のように記述します。変化のための式){処理;←これが繰り返し実行されます}for文のなかでは:(コロン)ではなく、;(セミコロン)を利用していることに注意しましょう。ループ文は実際に動かしてみないとその動きがわかりにくいので、実際に動かしてみましょう。main.xmlとLoopActivity.javaをそれぞれ以下のように変更します。i++){mTextView.append(String.valueOf(i));}}android.widget.TextViewのインポートを忘れないようにしましょう。実行してみると、以下のような画面になったでしょうか?今回は、0から4までの数字をTextViewに表示させてみました。最初にint型の変数iに0を挿入し(初期化処理)、iが5になるまで(繰り返すかどうか調べる)、iの値を1ずつ増加させています(変化のための式)。これまではTextViewのsetTextメソッドを利用していましたが、今回はappendメソッドを利用して、末尾にテキストを追記しています。追記するテキストは、String.valueOf(i)と指定しています。int型の変数iの値をString型に変更して、指定しているということです。今回は条件式としてi<5を指定しています。間違えやすいのですが、iは0で初期化したので、iは0から4までの値が入ります。5にはならないので注意してください。以下の課題にチャレンジしてみましょう。0以上10以下の偶数をTextViewに表示させる【動画】0以上10以下の偶数をTextViewに表示させる※画面右下のアイコンをクリックすると全画面表示になります解答はひとつではありません。以下に最もスマートな解答を示します。2として2ずつ数を増加させています。なっていることに注意して下さい。※画面右下のアイコンをクリックすると全画面表示になりますでは次に、while文を使ってみましょう。While文は以下の様に利用します。){処理;}では、while文を用い0以上5未満の整数を順番に表示してみましょう。LoopActivity.javaを以下のように書き換えます。for文で記述されたループの部分を削除し、以下の部分を追加します。){mTextView.append(String.valueOf(i));i++;}このコードの処理内容は、先ほどfor文を用いて記述したものと全く同じです。結果も同じになります。for文で記述したコードと比べて、どこの部分がループの処理なのかわかりづらくなっています。ループに関するコードを一行にまとめられることが、while文よりもfor文が好まれる理由です。whileループの中でi++;として変数iの値を1ずつ増加させていますが、これがなければどうなってしまうでしょう?i++;の部分を消去して実行してみましょう。なりましたか?しばらく反応がなかったあと、アプリケーションは強制終了するはずです。これは、iの値がいつまでたっても0のため、無限ループが発生しているためです。このように、whileループは注意して利用しなければアプリケーションにバグを発生させる原因となります。注意して利用しましょう。指定回数だけループする【動画】指定回数だけループする※画面右下のアイコンをクリックすると全画面表示になります今度は、繰り返しの回数を指定できるようにしてみましょう。繰り返す回数は、ユーザに入力してもらうことにします。文字列を入力および編集するために利用されるウィジェットは、EditText(エディットテキスト)と呼ばれます。main.xmlとLoopActivity.javaをそれぞれ以下のように書き換えます。/></LinearLayout></RelativeLayout>EditTextとButtonを新たに利用するので、インポート文に追加します。android.view.View.OnClickListener;ウィジェットの変数を追加します。{最後に、ボタンが押されたときの処理を記述します。{mTextView.append(String.valueOf(i));}}});}実行してみましょう。EditTextに入力した数字の回数だけループが回っていることが確認できます。EditTextに入力された文字列を取得するには、EditText型の変数に対して、以下のようにメソッドを実行します。mEditText.getText().toString()では、今度は入力した数までをTextViewに表示するのではなく、入力した数までの合計をTextViewに表示するようにしてみましょう。10と入力したときには55(0+1+2+3+4+5+6+7+8+9)と表示されれば正解です。EditTextに入力した数値までの合計をTextViewに表示する【動画】EditTextに入力した数値までの合計をTextViewに表示する※画面右下のアイコンをクリックすると全画面表示になります答えは、以下の様になります。i;}mTextView.setText(String.valueOf(sum));}});}まず最初に、int型の変数sum(合計値を入れる)を準備し、EditTextに入力された数字の回数だけsumにiを足しています。(配列の仕組み)※画面右下のアイコンをクリックすると全画面表示になります配列の仕組みプログラムの中では、たくさんのデータを扱う場合があります。20人学生がいるクラスのテストの点数を扱う場合等が、これにあてはまります。これまでに学んだ知識でこのようなプログラムを書こうとすると、どのようになるでしょうか?例えば、以下のように書けます。80;これは、とても面倒くさいですし、コードが複雑で読みにくくなってしまいます。このような場合に利用すると便利なプログラミングの仕組みが配列(Array)です。これまでに使ってきた変数(int等)ではひとつの値しか記憶することができませんでした。これに対して配列は、複数の値をまとめて記憶するという特徴を持っています。配列を使うと、先程のコードは以下のように記述できます。80;Javaで配列を扱う際には、配列の宣言と、配列要素の確保が必要になります。test[];の部分で行っています。これは、testという名前のint型の変数を複数格納する配列を作る、という宣言です。このように、配列には同じ型の変数しか格納できないことに注意してください。配列要素の確保は下記の部分で行っています。int[20];これで、testという配列にはint型の変数を20個格納するよ、としています。配列への要素の代入は下記のように記述します。20;[]の中の番号は添字と呼ばれ、これによって配列の中の要素を指定しています。Javaの場合、添字は0からはじまるため、最大の番号は要素数-1となっています。今回の例の場合、test[19];が最後の要素となり、test[20]に数値を代入しようとするとエラーが発生するため注意して下さい。熟練のプログラマでもしやすいミスの一つです。アイコンをクリックすると全画面表示になります新規に「Array」というプロジェクトを作成します。以下の情報にあわせて、各項目を入力して下さい。>」ボタンをクリックしてください。>」ボタンをクリックしてください。>」ボタンをクリックしてください。Noneまっさらな状態でアプリを実行し、エラーがでないことを確認します。World!」と表示されていればOKです。配列とループ【動画】配列とループ※画面右下のアイコンをクリックすると全画面表示になります実際にプログラムの中で配列を利用する際には多くの場合、先ほど学習したループが併用されます。配列に格納した点数を順番に表示するようにしてみます。main.xmlとArrayActivity.javaをそれぞれ以下のように変更します。/></RelativeLayout>インポート文を以下のようにします。",");}}}以下のように表示されるはずです。",");}上記の部分が重要です。先ほど学んだfor文を利用することで、test[i]のような形で配列の要素にアクセス出来ます。配列に入っている全要素の平均を表示する【動画】配列の入っている前要素の平均を表示する※画面右下のアイコンをクリックすると全画面表示になりますでは、この配列testの中に含まれる数値の平均をTextViewに表示して下さい。答えは、以下のようになります。5;mTextView.setText(String.valueOf(mean));この配列の平均値は、48でしたね。※画面右下のアイコンをクリックすると全画面表示になりますここまで配列を扱う際には、配列の宣言と要素の確保、という2つの作業を2つの文で記述していました。具体的には、以下の部分です。int[5];1行目で配列の宣言を行い、2行目で要素の確保を行っています。実は、この2つの処理は1行にまとめて記述することも可能です。int[5];またさらに、予め配列の要素が分かっている場合には以下のように記述することも可能です。};このように記述することで、配列の宣言と要素の確保に加えて、配列の初期化も一度に行うことが出来ます。ArrayActivityで利用する配列の初期化を、上記の方法で行ってみましょう。※画面右下のアイコンをクリックすると全画面表示になります配列の要素数(長さ)を取得するには、どうすれば良いのでしょうか?先程のforループでは、下記のようにして、配列の要素数を直接記述していました。test[i];}Javaでは、配列変数に続けて.lengthと記述すると配列の長さを取得することができます。先程のコードでは下記のように記述することで、要素の数「5」を取得出来ます。test.lengthこれらを用いることで、先程のforループは以下のように記述することができるようになります。test[i];}配列の要素数を知ることで、コードの記述を楽に行うことができるようになります。クラスフィールド【動画】クラス(フィールド)について※画面右下のアイコンをクリックすると全画面表示になります先ほど記述したArrayActivity.javaの先頭には、以下のような記述があり、その中に様々な処理を記述しました。ArrayActivityに注目してください。ここでは、ArrayActivityという名前のクラスを定義しています。クラスとはなんなのでしょうか?簡単にいえば、ひとつひとつのモノの設計図のようなものです。ここでは、ArrayActivityという画面をひとつのモノとして捉え、その設計図を記述しています。理解しづらいので、現実世界のものに置き換えてクラスを理解していきましょう。今回は、「車」というモノに着目し、プログラムを考えていきます。車は、どのようなデータを持っているでしょうか。それぞれの車にはナンバーが振られていますね。それぞれの車にはガソリンが積まれています。車によって乗車可能な人数も違いますね。これらは、いわば車の「性質」であると考えられます。乗員数これらの性質を持つ車のクラスは、以下のように記述できます。crew;}このように、クラスの性質を表す仕組みは、フィールドと呼ばれます。フィールドは、コード上では変数を用いて実現されます。※画面右下のアイコンをクリックすると全画面表示になります前節では、フィールドをまとめてクラスを宣言してみました。クラスを実際に利用する際には、その車がどんなナンバーを持つのか、どれだけのガソリンを積んでいるのか、何人乗れるのか、といった具体的なデータを持たせる必要があります。その為に必要になるのが、オブジェクトの作成という作業です。クラスは設計図である、といいましたが、設計図から実際の車を作る、と考えるとわかりやすいでしょう。12345というナンバーを持ち、20リットルのガソリンを積む、4人乗りの”TestCar”という名前の車を作成するには以下のようにします。4;このようにして作成された一つ一つの車の事を、インスタンス(実体)と呼びます。クラスという設計書を用いてインスタンス(1台1台の車)を作成するのです。インスタンスのフィールドにアクセスするには、”.”を使います。実際にクラスを作成し、TextViewに内容を表示するプログラムを作成しましょう。新規に「Car」というプロジェクトを作成します。以下の情報にあわせて、各項目を入力して下さい。>」ボタンをクリックしてください。>」ボタンをクリックしてください。>」ボタンをクリックしてください。Noneそのまま起動して、エラーがでないことを確認するまっさらな状態でアプリを実行し、エラーがでないことを確認します。World!」と表示されていればOKです。【動画】オブジェクトの作成2※画面右下のアイコンをクリックすると全画面表示になりますmain.xmlとCarActivity.javaを以下のように編集します。+"人です\n");}}以下のように表示されたでしょうか。新しく作成したインスタンスに、それぞれの値を代入しています。メソッド【動画】メソッド※画面右下のアイコンをクリックすると全画面表示になります前節では、クラスにフィールドを定義することで、様々なモノの性質をプログラムで表現する方法について学びました。車には以下のような機能があると考えられます。車の機能ナンバーを決めるガソリンを入れる乗員数を決める車の性能や性質(ナンバー、ガソリン、乗員数)を表示するこれらの機能は、車の性質を変更するものであるといえます。機能は、クラスのメソッドとして実現されます。これまでの講義の中で、メソッドの説明を少しだけ行った事を覚えているでしょうか。メソッドとは、様々なモノの機能をまとめる働きをするものです。メソッドには普通、複数の処理を記述します。メソッドを作ることを、メソッドを定義する、といいます。先ほどあげた車の機能を持つクラスは以下のように実装されます。CarActivity.javaを以下のように編集しましょう。先ほど定義したCarクラスを以下のようにします。text;}}さらに、TestCarインスタンスを扱っていた部分を以下のように変更します。これまでと同様に、オレンジの部分を追記/し、灰色の部分を削除します。+"人です\n");TestCar.setNumber(12345);TestCar.setGas(20.0);TestCar.setCrew(4);mTextView.setText(TestCar.getText());先ほどと同じ画面になったのではないでしょうか。先程までは、直接インスタンスのフィールドにアクセスして値を変更していましたが、今回はメソッドを介してフィールドにアクセスしていることがわかるでしょうか?Javaの様なオブジェクト指向言語では、カプセル化、といって直接インスタンスのフィールドを書き換えることが出来ないようにし、メソッドを介してフィールドの値を変更する事が一般的です。※画面右下のアイコンをクリックすると全画面表示になりますカプセル化のメリットはいくつかありますが、ひとつはありえない値をインスタンスのフィールドに代入できなくすることで、プログラムのバグを減らす事ができることです。-10.0;のようなおかしな代入が可能です。(ガソリンの残量が負数って奇妙ですよね)カプセル化の仕組みを用いる事により、このようなおかしな値の代入を防ぐことが可能になります。先程のコードを以下のように書き換えましょう。Carクラスの以下のメソッドを書き換えます。c;}}このようにすることで、負数がインスタンスのフィールドに代入されることを防ぐことができます。-10のようにして直接フィールドの値を書き換えることができてしまいます。クラスの外から直接値を書き換えることを防ぐには、フィールドをprivateメンバとして定義します。(クラスに定義されているフィールドやメソッドをまとめてメンバといいます)。具体的には以下のようにします。text;このように、privateメンバとしてフィールドを定義することで、クラスの外から勝手にアクセスすることができなくなります。setNumber()やsetGas()といったメソッドはクラスの外からアクセスすることが一般的ですから、publicメンバとして定義することが一般的です。まとめると、Carクラスは以下のようになります。text;}}まとめると、データと機能をひとまとめにし、メンバを保護する機能をカプセル化といいます。カプセル化を行うことで、誤りの起きにくいプログラムを作成することができるようになり、生産性が上がります。フィールドはprivateメンバとして、メソッドはpublicメンバとして定義することが多い、と覚えておいて下さい。他のファイルに定義する【動画】他のファイルに定義する※画面右下のアイコンをクリックすると全画面表示になりますこれまでは、CarActivity.javaというファイルの中にCarクラスを定義してきましたが、長くなってきたので独自のファイルに定義しましょう。多くの場合、ひとつのファイルにはひとつのクラスを定義します。Classを選択します。Class画面が表示されるので、Name:にCarと入力し、Superclassは「java.lang.Object」になっている事を確認して「Finish」ボタンをクリックします。新しく作成したCar.javaを、以下のように編集します。text;}}CarActivity.javaからは、Carクラスの部分をまるごと削除しましょう。CarActivity.javaはこのようになっているはずです。Car();TestCar.setNumber(12345);TestCar.setGas(20.0);TestCar.setCrew(4);mTextView.setText(TestCar.getText());}}先程までと同じように実行できたでしょうか。コンストラクタ【動画】コンストラクタ※画面右下のアイコンをクリックすると全画面表示になりますこれまでクラスの中には、フィールドとメソッドを記述してきました。これらに加えて、クラスの中にはコンストラクタというものを定義することができます。コンストラクタは、インスタンスが生成されるときに呼び出される特別なメソッドです。(厳密にはメソッドではありませんが、そのような理解で構いません)。コンストラクタは、必ずクラス名と同じである必要があります。コンストラクタには、インスタンス生成時の初期値を設定する等の処理を記述することが一般的です。車クラスであれば、ナンバーやガソリン、乗員数等のフィールドの初期値に0を設定する、といった処理をまとめておくことができます。初期値を設定するCarクラスのコンストラクタを定義してみましょう。){では実際に、コンストラクタの働きをみてみましょう。CarActivity.javaを以下のように編集(利用しているセッタを削除)します。フィールドに値をセットするメソッドのことをセッタ、フィールドの値を取得するメソッド(CarクラスではgetText())のことをゲッタといいます。Car();TestCar.setNumber(12345);TestCar.setGas(20.0);TestCar.setCrew(4);mTextView.setText(TestCar.getText());コンストラクタで設定した初期値が反映されていたでしょうか。メソッドのオーバーロード【動画】メソッドのオーバーロード※画面右下のアイコンをクリックすると全画面表示になりますJavaでは、オーバーロードという仕組みを利用することで、同じ名前を持つメソッドを複数定義することができます。Carクラスに定義されているセッタ(setNumber,setGas,setCrewメソッド)削除して代わりに以下のメソッドを追加してください。Carクラスに定義されているセッタを全て削除します。){//省略}かわりに、以下のコードを追加します。getText(){このクラスには、setCar()メソッドが4つもあります。このように、同じ名前の複数のメソッドを同じクラス内に定義することをメソッドのオーバーロードといいます。メソッドをオーバーロードする際には必ず各メソッドの引数の型、個数が異なるようにしなければなりません。c)というようにそれぞれのメソッドの名前は同一でも引数の型や個数が異なっていることがわかります。それではこれらのメソッド使ってみましょう。今回は、わかりやすいように複数のインスタンスを生成します。main.xmlを編集してTextViewを複数設置しましょう。/></LinearLayout></RelativeLayout>CarActivity.javaを以下のように編集します。Car();TestCar3.setCar(67891,11.1,8);mTextView3.setText(TestCar3.getText());}}以下のように表示されたでしょうか。setCar()という同じメソッドを実行したにも関わらず、実際に行われている処理が異なることがわかると思います。似たような複数の処理をオーバーロードしておけば、ひとつのメソッド名を覚えておくだけで、最適な処理を行わせることが可能になります。コンストラクタのオーバーロード【動画】コンストラクタのオーバーロード※画面右下のアイコンをクリックすると全画面表示になりますメソッドと同様に、コンストラクタもオーバーロードすることが可能です。インスタンスの生成時に値のセットも行う便利なコンストラクタを作ってみましょう。){CarActivity.javaのTestCar2インスタンスの生成を行っている部分を、以下のように変更し、オーバーロードしたコンストラクタを利用するようにしてみます。アイコンをクリックすると全画面表示になります継承の基本クラスについて、理解が深まったでしょうか。Activity)にも注目しましょう。赤字と青字の部分をまとめると、Activityという設計図を参考にしてArrayActivityという設計書を定義する、という意味になります。このように、他のクラスを利用して新しいクラスを定義することを、クラスを拡張(extends)する、といいます。新しいクラスには、既存のクラスのメンバ(フィールドやメソッド)が受け継がれます。この仕組みを、継承(inheritance)と呼び、既存のクラスをスーパークラス、新しく作成したクラスをサブクラスと呼びます。車クラスを拡張してトラッククラスを作成してみましょう。CarクラスをスーパークラスとしたサブクラスとしてTrackクラスを作成する、ということです。先ほどと同じ手順で新しいクラスファイルを作成します。Classウィンドウでは、NameにTrack、superclassにcom.rainbowapps.car.Carと指定します。新しく作成したトラッククラスを以下のように編集します。"kgです";}}トラッククラスには、積荷の重さを示すloadフィールドと、積荷の重さをセットするsetLoad()メソッド、積まれた積荷の重さを取得するgetLoad()メソッドを実装しました。トラッククラスを実際に使ってみましょう。Track();TestTrack.setCar(67891,11.1,8);TestTrack.setLoad(500);mTextView3.setText(TestTrack.getText());mTextView3.append(TestTrack.getLoad());TrackクラスはCarクラスを継承しているので、setCar()やgetText()といったCarクラスのメソッドを利用することができますし、Trackクラスにしか存在しないsetLoad()メソッド等も当然利用することが出来ています。継承とオーバーライド【動画】継承とオーバーライド※画面右下のアイコンをクリックすると全画面表示になります先程は、メソッドのオーバーロードについて説明しました。オーバーロードは、メソッド名が同じで引数の形式が異なるメソッドを定義すること、でした。クラスはオーバーライドという仕組みも持っています。オーバーライドとは、スーパークラスと全く同じメソッド名、引数の数、型を持つメソッドを定義すること、です。オーバーロードとオーバーライドは似ていますが、全く違う仕組みなので混ざらないようにしましょう。CarクラスのgetText()メソッドをオーバーライドしてみましょう。サブクラスからスーパークラスのメンバにアクセスできるようにCarクラスを編集します。text;privateに設定をしておくと、クラスの外からのアクセスができなくなってしまうので、サブクラスからもアクセスできなくなってしまいます。サブクラスとスーパークラスは密接な関係があることが多いので、これでは不都合です。代わりにprotectedを指定することで、例外的にサブクラスからはアクセスできるようになります。Trackクラスを以下のように編集します。text;}}CarクラスのgetText()メソッドと異なり、今回オーバーライドしたTrackクラスのgetText()では、積荷の重さも表示されるようになっています。コンストラクタをオーバーライドし、様々な要素を指定して初期化できるようにしました。c);では、スーパークラスのコンストラクタを呼び出しています。最後に、CarActivity.javaのTrackクラスを利用している部分を以下のように書き換え、今回作成したコンストラクタと、オーバーライドしたgetText()メソッドを利用するようにしてみます。Track();TestTrack.setCar(67891,11.1,8);TestTrack.setLoad(500);mTextView3.setText(TestTrack.getText());mTextView3.append(TestTrack.getLoad());以下のような画面になったでしょうか。以上で、Javaにおけるクラスと継承の説明を終わります。これだけでも1冊の本が書けるくらいの内容で、とても全てを説明しきれていません。今回は、Androidアプリケーション開発に最低限必要な部分に絞って説明を行いました。