Java プログラマー早期育成ドリルコードリーディング編 解答 2 版 2017 年 1 月 本資料は UFN25W:Javaプログラマー早期育成ドリルコードリーディング編 をご購入頂いた方にのみ提供される資料です 資料内容の転載はご遠慮ください 本解答は UFN25W:Javaプログラマー早期育成ドリルコードリーディング編 の初版および2 版に対応しています
コラム一覧 このドリルの解答では すべての構文の紹介はしていません 間違えやすい部分に関しては 解説 ( コラム ) として紹介しています コラム1 基本データ型 ( プリミティブ型 ) と参照型 コラム2 基本データ型の型変換 コラム3 条件分岐と論理演算子 コラム4 さまざまな繰り返し処理 コラム5 オブジェクト指向の用語まとめ 1 コラム6 クラスの継承 ~スーパークラスとサブクラス アクセス修飾子 コラム7 オブジェクト指向の用語まとめ 2 コラム8 クラスの拡張 ~ 抽象クラスとインタフェース コラム9 例外処理の基本 P4 P7 P10 P12 P16 P20 P22 P23 P25
1 クラスと main() メソッド コードには [ 1 2 3 ] つのクラス定義が記述されています Aクラスは [ 1 ] 行目から [ 3 ] 行目までです Bクラスは [ 5 ] 行目から [ 7 ] 行目までです StartUpクラスは [ 9 ] 行目から [ 13 ] 行目までです main() メソッドは [ 10 ] 行目から [ 12 ] 行目までに記述されています main() メソッドのあるクラスは [1 2 3 ] つです 2 変数とデータ型 String name = "ABCDEFG"; String name = "123456"; int number = -123456; boolean flag = false; boolean flag = true; 3
コラム 1 基本データ型 ( プリミティブ型 ) と参照型 データ型には基本データ型 ( プリミティブ型 ) と参照型があります 参照型の1つとして 文字列を扱うString 型があります 基本データ型と参照型との大きな違いは 基本データ型では変数自体が値を格納しているのに対し 参照型では参照 ( アドレス値 ) を格納している点です 以下のコードの場合 変数 str1 にはアドレス値 ( 分かりやすいように 100 としています ) が入り アドレスが示す領域に実際の値である "Welcome To " が入っています String str1 = "Welcome To "; 100 str1 100 "Welcome To " このため データの代入を行った場合 基本データ型は同じ値を格納した別々の領域と なるのに対し 参照型では変数は別々でも参照している値は同じである場合があります 基本データ型 1. int number1 = 100; 2. int number2 = number1; number1 number2 100 100 変数に値が直接 代入される 参照型 変数に参照 ( アドレ ス値 ) が代入される 1. String name1 = " 鈴木 ; name1 2. String name2 = name1; name2 鈴木 " 4
3 配列の定義 コード 1 A コード 2 B 4 コマンドライン引数の利用 コマンド 1 処理は 0 回実行されます コマンド 2 処理は 2 回実行されます コマンド 3 3 処理は回実行されます コマンド 4 処理は 1 回実行されます 5
5 演算子 int num = 2 + 3 * 4; num 14 int num = 3 * 6; num 18 double num = 2 * 3.14; num 6.28 double num = 10 / 4; num 2.0 double num = 10.0 / 4.0; num 2.5 double num = 10.0 / 4 ; num 2.5 int num = 10 % 4; num 2 int value = 1; boolean flag = value == 1 ; flag true int value = 100; boolean flag = value!= 100 ; flag false int value = 3; boolean flag = value > 3; flag false int value = 3; boolean flag = value >= 3; flag true 6
コラム 2 基本データ型の型変換 基本データ型を使用した式の演算や代入を行う場合には データ型の変換が必要になる ことがあります このような場合に行われる変換を型変換 ( キャスト ) といいます 型変換には暗黙的型変換と明示的型変換があります 暗黙的型変換代入において 左辺の型のサイズが右辺の型より大きい場合 左辺の型に自動的に型変換されます 以下のコードでは 右辺の計算結果はint 型です 左辺のdouble 型はint 型より大きいため 暗黙的な型変換が行われます double num = 10 / 4; また 式の中に複数のデータ型が混在する場合 その中で最もサイズの大きな型に型変 換されます この型変換も自動的に行われます 以下のコードでは 左辺に double 型と int 型が混在しているため double 型に暗黙的に変換されます double num = 10.0 / 4; 明示的型変換 左辺の型のサイズが右辺の型より小さい場合 自動的には型変換が行われず コンパイル エラーが発生します 開発者自身で意識的に変換する必要があります 書式 ( 変換する型 ) 変換する値 int num =(int) (10.0 / 4); 型変換の動きを理解していないと 演算の結果を誤って解読してしまう場合があります 注意しましょう 7
6 if 文による条件分岐と論理演算子 1 処理 1 が実行される条件式 score <= 100 score < 0 処理 2 が実行される条件式 score % 10 > 0 7 if 文による条件分岐と論理演算子 2 変数 result の値 値 1 と値 2 の組み合わせ 合格 値 1 が 100 値 2 が 40 値 1 が 90 値 2 が 70 補欠合格 値 1 が 80 値 2 が 80 値 1 が 80 値 2 が 70 不合格 値 1 が 80 値 2 が 50 値 1 が 70 値 2 が 70 8
8 switch 文による条件分岐 変数 number の値 結果 0 処理 1 が実行される 2 処理 2 が実行される 処理 3 が実行される 2.5 コンパイルエラーになり実行できない 3 何も起こらない ( コンパイルエラーも発生しない ) 9
コラム 3 条件分岐と論理演算子 条件分岐を行う構文には 以下の 2 つがあります if 文 switch 文 if 文は if の後の丸括弧の中に boolean 型で評価できる条件式を記述します 条件式が真 (true) か偽 (false) かによって 処理の流れが変わります switch 文は switch の後の丸括弧に指定する式の値が 整数型(char 型 byte 型 short 型 int 型 ) String 型 列挙型である必要があります これ以外のデータ型 ( 浮動小数点型など ) を式の値にした場合はエラーが発生します switch 文の各 caseラベル内の処理にはbreakまたはreturn 文のいずれかを記述します ただし caseラベルだけを連続で記述する場合は breakを書く必要はありません 1. switch(number){ 2. case 0: 3. case 1: numberが0または1の場合 4. 同じ処理をするため 5. break; case 0: に対応する 6. case 2: breakを記述しません 7. 8. break; 9. default: 10. 11. break; 12. } また if 文のようにboolean 型で評価する条件式を記述する場合 論理演算子を使うことがありま す かつ ないしは または の動きをする論理演算子を以下に示します 演算子 働き 機能 & かつ 2つの式がともに真の場合はtrue それ以外はfalseを返す または 2つの式が1つ以上真の場合はtrue それ以外はfalseを返す && かつ式を左から評価し 偽に当たると false を返し 残りを評価しない または式を左から評価し 真に当たると true を返し 残りを評価しない 通常 && 演算子の評価結果と & 演算子による評価結果は同じです しかし && および 演算子は 左辺の評価結果によっては右辺を評価しません このような挙動をショートサーキット評価 ( または短絡評価 ) と呼びます 10
9 while 文による繰り返し コード1 処理 は 5 回実行されます コード2 処理 は 4 回実行されます コード 3 処理は 回実行されます 10 for 文による繰り返し コード 1 処理 は [ 4 5 6 ] 回実行されます コード 2 処理 は [ 4 5 6 ] 回実行されます コード 3 処理 は [ 5 9 10 ] 回実行されます 11 拡張 for 文による繰り返し コード 1 Hello, Java World コード 2 310 コード 3 11
コラム 4 さまざまな繰り返し処理 繰り返しを行う構文として 以下の4つがあります while 文 do - while 文 ( ドリルでは扱いません ) for 文 拡張 for 文 while 文は繰り返しのたびに条件が評価される前判定ループ do - while 文は繰り返しのたびに処理の最後で条件が評価される後判定ループです 前判定ループは 最初から条件を満たさない場合 1 度もループ内の処理を行うことなく後続の処理を行います 後判定ループは 最初から条件を満たさない場合でも 1 度はループ内の処理を行った上で 後続の処理を行います また 拡張 for 文は配列などの値の集合からなるデータ群 ( コレクション ) の先頭から末尾までの各要素に 順番に同様の処理を繰り返すときに使用する構文です 拡張 for 文の構文を以下に示します このとき 反復変数のデータ型はコレクションの要素と同じものを使用します 書式 for( データ型反復変数 : コレクションの参照変数 ){ [ 各要素に対して実行する処理 ;] } また 以下の構文を使用することで 繰り返し処理を制御できます break 文繰り返しを終了して 次の処理へ移動 continue 文繰り返し処理のブロックの最後まで残りの処理をスキップする 12
12 メンバ変数とメソッド Employeeクラスには [ 2 ] 個のメンバ変数が定義されています A 部分には [ メンバ変数 メソッド ] の定義が記述されています B 部分には [ メンバ変数 メソッド ] の定義が記述されています 13 メソッドの定義 1 コード 1 戻り値を [ 返す 返さない ] メソッドです メソッドの名前は [ void test1 ] です コード 2 引数が [ ない ある ] メソッドです 戻り値を [ 返す 返さない ] メソッドです コード 3 引数が [ ない ある ] メソッドです 戻り値のデータ型は [ String int ] です 引数の変数名は [ msg no ] です コード4 引数の数は [ 2 戻り値の数は [ ] 個です 1 ] 個です 14 メソッドの定義 2 order() メソッドには [ boolean ] 型の引数が定義されています 引数名は [ ispremiumuser ] です order() メソッドを実行することで メンバ変数 [ orderdate ] に 実行時の日時が設定されます また order() メソッドの引数名 [ ispremiumuser ] の値がtrueの場合は メンバ変数 [ deliverymode ] に [ 即日配送 ] の文字列が 設定されます order() メソッドの引数名 [ ispremiumuser ] の値がfalseの場合は メンバ変数 [ deliverymode ] に [ 翌日配送 ] の文字列が 設定されます order() メソッドは戻り値を [ 返します 返しません ] 13
15 メソッドのオーバーロード コード 1 A, B, C コード 2 B, C 16 コンストラクタの定義 1 B, D 17 コンストラクタの定義 2 コード 1 このクラスのコンストラクタは 2 個です コード 2 このクラスのコンストラクタは 1 個です 18 インスタンス生成 emp1 name = ["Unknown" ] number = ["1234" ] emp2 name = ["Sato" ] number = [ "9876" ] emp3 name = [ "Yamada" ] number = [ "3210" ] 14
19 メソッドの呼び出し 1 A 部分にはメソッドの [ 定義 呼び出し ] が記述されています B 部分にはメソッドの [ 定義 呼び出し ] が記述されています C 部分にはメソッドの [ 定義 呼び出し ] が記述されています D 部分にはメソッドの [ 定義 呼び出し ] が記述されています E 部分にはメソッドの [ 定義 呼び出し ] が記述されています F 部分にはメソッドの [ 定義 呼び出し ] が記述されています 20 メソッドの呼び出し 2 コード 1. public class Sample{ 2. 3. public int add(int x, int y){ 4. return x + y; 5. } 6. 7. public double div(int x, int y){ 8. return (double)x / y; 9. } 10. 11. public void test(int x){ 12. } 13. 14. public void test(string x){ 15. } 16. 17. public void test(int x, String y){ 18. } 19. 20. public void test(string x, int y){ 21. } 22. 23. } 実行コード s.test(100, "123"); a int answer = s.add(5, 2 ); b s.test("123", 100); c double result = s.div(5, 2 ); d s.test(100); e s.test("123"); f 15
コラム 5 オブジェクト指向の用語まとめ 1 ここまでの問題で登場するオブジェクト指向の用語を以下にまとめます クラスオブジェクトのひな形 オブジェクトを作る際の設計図に相当するクラス内部にはデータと処理を定義できる インスタンスクラス ( 設計図 ) をもとに作られた個々の実体のことオブジェクトとほぼ同じ意味を持つ ネコクラス 名前 色 生成 ネコオブジェクト トラちゃん チャトラ ネコオブジェクト コテツくん グレートラ 具体的な値を持った個々の実体 メンバ変数オブジェクトが持つデータのこと メソッドオブジェクトが持つ処理のこと 引数メソッドの実行のために外部から与えるデータのこと 戻り値メソッドの結果として外部に返す値のこと オーバーロード同名メソッドを多重定義すること コンストラクタインスタンス生成時に動作する特殊なメソッドインスタンス生成時にメンバ変数の初期化などを行う場合に作成する 16
21 サブクラスの定義 1 [ A B ] クラスは [ A B ] クラスを継承した [ サブ スーパー ] クラスです C クラスのスーパークラスは [ ありません D クラスです ] C クラスのサブクラスは [ ありません B クラスです C クラスです ] D クラスのスーパークラスは [ ありません B クラスです C クラスです ] D クラスのサブクラスは [ ありません B クラスです C クラスです ] E クラスのスーパークラスは [ ありません B クラスです ] E クラスのサブクラスは [ ありません C クラスです D クラスです ] 22 サブクラスの定義 2 [ Book ] クラスは [ Item ] クラスのサブクラスです サブクラスにはスーパークラスから継承したメンバ変数が [ 2 ] 個 メソッドが [ 1 ] 個あります サブクラスで独自に定義したメンバ変数は [ 1 ] 個あります 23 サブクラスのインスタンス Item オブジェクト Book オブジェクト メンバ変数 name メンバ変数 price メンバ変数 author showinfo() メソッド showdetail() メソッド setname() メソッド setprice() メソッド setauthor() メソッド 17
24 オーバーライドの定義 dosomething1() メソッドは スーパークラスのメソッドをサブクラス側で [ オーバーロード オーバーライド ] しています これにより dosomething1() メソッドが再定義されます dosomething2() メソッドは スーパークラスのメソッドをサブクラス側で [ オーバーロード オーバーライド ] しています これにより dosomething2() メソッドが多重定義されます 25 サブクラスの使用 a 行の実行により呼び出されるコンストラクタ X クラスのコンストラクタ ( 引数なし ) Y クラスのコンストラクタ b 行の実行により呼び出されるメソッド Y クラスの returninfo() メソッド 26 super キーワードの使用 1 実行コード 1 商品名 :null 価格 :0 サイズ :M 実行コード 2 商品名 : ネコ柄 T シャツ 価格 :1500 サイズ :XS 18
27 super キーワードの使用 2 i1 name = [ " 名前なし " ] price = [ 0 ] w1 name = [ " 名前なし " ] price = [ 0 ] size = [ "Free" ] w2 name = [ " 白 Yシャツ " ] price = [ 3000 ] size = [ "L" ] 28 アクセス修飾子 BaseClass クラスの dosomething() メソッドは SampleClass クラス内から アクセス可能である BaseClass クラスのメンバ変数 basename は DerivedClass クラス内から アクセス可能である BaseClass クラスのメンバ変数 basename は SampleClass クラス内から アクセス可能である BaseClass クラスのメンバ変数 basecount は DerivedClass クラス内から アクセス可能である DerivedClass クラスの dosomething() メソッドは SampleClass クラス内から アクセス可能である DerivedClass クラスのメンバ変数 derivedname は BaseClass クラス内から アクセス可能である SampleClass クラスの dosomething() メソッドは BaseClass クラス内から アクセス可能である BaseClass クラスの setter および getter は DerivedClass クラス内から アクセス可能である 19
コラム 6 クラスの継承 ~ スーパークラスとサブクラス アクセス修飾子 継承とは 既存のクラス定義を引き継いで 新たなクラスを定義することです 新しい クラスの定義時には既存のクラスとの差分のみを定義するだけで済むため クラスの再利 用性が向上します ネコクラス スーパークラス 名前 色 飼いネコクラス 図には見えていないが スーパークラスのメンバの 名前 と 色 を受け継いでいる サブクラス 飼い主の名前 お気に入りのオモチャ 再利用性の高いクラスを作るためには クラス間の依存関係を少なくすることが重要です そのため サブクラスでスーパークラスから受け継いだメンバ変数 ( 上図における 名前 や 色 ) の初期化を行う場合は サブクラスのコンストラクタで直接初期化処理を行うのではなく サブクラスのコンストラクタの中からスーパークラスのコンストラクタを呼び出します そうすることで 仮にスーパークラスに変更が発生しても ( 上図における 名前 を ネコの名前 に変更するなど ) サブクラスへの影響を最小限に抑えることができます また クラスのメンバ ( メンバ変数やメソッドなど ) のアクセス範囲はアクセス修飾子 によって決まります よく使用するアクセス修飾子を以下に示します 修飾子 private 機能 定義したクラスの内部からのみアクセス可能 public 定義したクラスの外部からもアクセス可能 ( アクセス制限なし ) 20
29 インタフェースの定義 コードの中にはインタフェースが [ 2 ] 個定義されています インタフェース内には メソッドの [ シグニチャ 実装 ] が含まれています メソッドの [ シグニチャ 実装 ] を記述することはできません 30 インタフェースの実装 C, D, E 31 参照型の型変換 1 回目の繰り返し処理における実行コード g 行で呼び出されるメソッド A 3 回目の繰り返し処理における実行コード g 行で呼び出されるメソッド B 21
コラム 7 オブジェクト指向の用語まとめ 2 ここまでの問題で登場するオブジェクト指向の用語を以下にまとめます 継承 既存のクラス定義を引き継いで 新しいクラスを定義すること クラスオブジェクトのひな形 オブジェクトを作る際の設計図に相当するクラス内部にはデータと処理を定義できる スーパークラス 2つのクラスが継承関係にあるときの 継承元になるクラス サブクラス 2つのクラスが継承関係にあるときの 継承先になるクラスサブクラスはスーパークラスのメンバ ( メンバ変数やメソッドなど ) をすべて受け継ぐ メソッドオブジェクトが持つ処理のこと特殊なものとしてはコンストラクタなどがある 抽象メソッド引数や戻り値の型だけを定義した空のメソッド ( シグニチャ ) オーバーライドスーパークラスと同じ名前 引数 戻り値の型のメソッドをサブクラスで定義することスーパークラスから引き継いだ同名メソッドの再定義 ( 用語が同名メソッドを多重定義すること ( オーバーロード ) と似ているが 異なる概念 ) インタフェース 引数や戻り値の型だけを定義した空のメソッド ( シグニチャ ) の集まり 22
コラム 8 クラスの拡張 ~ 抽象クラスとインタフェース 抽象クラスとインタフェースは どちらも単体ではインスタンスの生成ができません 抽象クラス もインタフェースも同名メソッドの多様性 ( 本質的には同じでも詳細が異なる処理を 同じ命令名を 使って実行する仕組み ) を高めるための仕組みと言えます ここで 再生 停止 という処理を考えてみましょう 例えば 音楽プレーヤーの場合は 再生 処理によって 音が流れ 停止 処理によって 音が止まる でしょう これに対して 動画プレーヤーの場合は 再生 処理によって 画像と音が流れ 停止 処理によって 画像と音が止まる でしょう 本質的にはどちらも同じ 再生 と 停止 ですが 処理の詳細は異なります このように 処理の詳細は異なっていても本質的に同じ処理がある場合は あえて同じ名前にそろえることで 新しくクラスを開発する開発者にとっては複数の名前を命名する手間が省けます また 既存クラスを使用する開発者にとっては 複数の名前を覚えて使い分ける手間が省けます クラスに対する同名メソッドの多様性 ( ポリモフィズムとも言います ) を実現するために抽象クラスとインタフェースのどちらを使用するかは しばしば難しい問題となることがあります 抽象クラスとインタフェースの使い分けの推奨を以下に示します 幅広い範囲の種類の異なるオブジェクトで使用できる機能を作成する場合は インタフェースを使用する例えば 音楽プレーヤー だけでなく カメラ ゲーム機 にも 再生 と 停止 機能を作成する場合 音楽プレーヤー カメラ ゲーム機 などの間で継承関係を見出すことは困難な場合があります インタフェースは継承関係に関係なく使用できます 作成する機能に対して複数のバージョンが必要な場合は抽象クラスを使用する抽象クラスの場合 抽象クラス ( 継承関係におけるスーパークラス ) を更新することにより すべてのサブクラスに自動的に変更が反映されます インタフェースにおいて新しいバージョンが必要な場合は 別名の新しいインタフェースを作成する必要があります 作成するクラスに対して共通の実装済み機能を提供する場合は 抽象クラスを使用する 抽象クラスには実装済みメソッドを含めることができますが インタフェースでは 実装済みメソッドを含めることはできません 小さな機能の場合は インタフェースを 大きな機能の場合は 抽象クラスを使用する 1 つのクラスに対して複数のインタフェースの実装は可能ですが 複数のクラスの継 承はできません 23
32 例外処理 1 値 結果 0 処理 1 が実行される 処理 2 が実行される 3 処理 3 が実行される 5 処理 4 が実行される 33 例外処理 2 B A C D 34 ユーザー定義例外と例外のスロー 値が 5 の場合 " お買い上げありがとうございます " 値が 50 の場合 " 在庫不足です " 値が 10 の場合 " お買い上げありがとうございます " 値が 25 の場合 " 購入数が多すぎます " 24
コラム 9 例外処理の基本 Java では 例外処理の方法として 以下の 2 通りがあります try-catch 文を使用した例外処理 throws キーワードを使用した例外処理 それぞれの書式は以下のとおりです 書式 try{ [ エラーが起こる可能性のある処理 ;] }catch( 例外の型 [ 変数名 ]){ [ 例外処理 ;] }finally{ [ 例外の有無にかかわらず実行する処理 ;] } 書式 [ 修飾子 ] 戻り値の型メソッド名 ( 引数 ) throws 例外クラスの型 { } [ エラーが起こる可能性のある処理 ;] try-catch 文は エラーが発生した場合 プログラムの強制終了を防ぎ エラーに対処できます throwsキーワードを使用することにより 発生した例外オブジェクトを呼び出し元に通知できます throwsを使用した場合 最終的には呼び出し側でtry-catch 文の記述が必要になります また 例外を明示的に発生させることができます 業務ルールに反した処理を行った場 合などに例外を発生させる場合に使用できます 書式 throw 例外オブジェクト ; 25