スッキリわかるJava入門を読み終えたので簡単なレビューと学んだことのまとめを書きます。
かんたんレビュー
全編通してわかりやすい説明で、この本を選んでよかったと思っています。
ただ、前半(5章まで)はちょっと詰め込みすぎ感がありました。
読むばっかりでコードを書けないことが多くて退屈な部分も。
しかし中盤のオブジェクト指向からは、説明と練習問題の割合がちょうどよく楽しく学習できました。
読み終えるまでの所要時間は55時間ほどでした。
おすすめの勉強法
progateのjavaレッスン無料部分をやる → この本の5章までを軽く読む → 6章から本腰を入れて読む
progateの無料部分と、この本の5章まではほぼ同じ内容です。
ただ、progateの方がコードを書きながら学べて退屈しにくくなっています。
なのでまずprogateをやってから、この本の5章までを復習がてらに読み、6章からじっくり勉強しましょう。
こうすると前半部分で挫折しにくくなると思います。
この本の最も良い所はオブジェクト指向というわかりにくい部分について、初心者向けに丁寧にわかりやすく解説してくれる所です。
ですからオブジェクト指向以外の所は他で勉強して、オブジェクト指向はこの本で学ぶのが最適でしょう。
学んだこと
- 変数
- 条件分岐と繰り返し
- 配列
- メソッド
上記は割愛。
オーバーロード
・・オーバーロードとは
同じ名前のメソッドを定義すること。
・・用途
似た内容のメソッドを複数作りたい時に使う。
・・書き方
メソッドの引数を変える
add(int a, int b, int c){}
add(int a, int b){}
add(int a){}
・・呼び出し方
引数を変える。
add(a,b,c)
add(a,b)
add(a)
クラス
・・クラスの用途は3つ
1、ソースファイルを分割して分かりやすくする。
役割ごとにクラスを分ける。
呼び出し方:SubClass.test(); など「クラス名.メソッド名()」で呼び出せる。
2、newによる利用:インスタンスを産み出すために、そのクラスを利用する。
例
1 |
Hero h = new Hero(); |
3、extendsによる利用
別のクラスを開発する際、ゼロからつくると効率が悪いので、あるクラスを継承元として利用する。
オブジェクト指向
・・オブジェクト指向の思想
現実に似せて作り、現実に似せて動かす。
・・目的
人間に理解できるプログラム開発を実現する。
保守性や再利用性の向上。
・・方法
現実世界の人や物をオブジェクト化していく。
・・例
銀行を自動化(ATM)する場合。
お客さんから受付が要望聞く
お客「引き出しをお願い」
--本人確認フェーズ--
通帳とハンコを借りる。
通帳の情報から店内の帳簿を探す。
通帳の取引記録と店内帳簿の記録をを照合する。
本物か印鑑記録と照合する。
--本人確認フェーズ終了--
金庫からお金を持ってくる。
金額を計算する。
引き出し取引を通帳と店内帳簿に記録する。
お客さんにお金を渡す。
終了。
・必要なオブジェクト
受付オブジェクト
通帳オブジェクト
ハンコオブジェクト(本人確認オブジェクト)
店内帳簿オブジェクト
金庫オブジェクト
受付オブジェクト(インスタンス)がMainクラスで各オブジェクトに指令を出す。
インスタンス
◆イメージ
プラモデルの完成品
◆クラスとの違い
クラス:設計図・仕様書・どのような物かの概念
インスタンス:クラスを元に作り出された完成品
プラモデルで言うと
クラス:設計図+金型
インスタンス:完成品
◆実際のところ
newで生成したメモリ領域。
大きめのデータを入れるために確保されたメモリ領域。
◆インスタンスの生成
クラス名 変数名 = new クラス名();
↑↑
上記の変数にインスタンスが入っている。
(正しくはインスタンス領域の先頭アドレスが入っている)
例
1 |
Hero yuusya1 = new Hero(); |
◆this
this.は自分のインスタンスを示す。
◆has-aの関係
あるクラスが別クラスをフィールドとして利用する関係
Hero has-a Sword 勇者は剣を持っている。
コンストラクタ
・・コンストラクタとは
クラス名と同一名称で、戻り値の型が明記されていないメソッドのこと。
new をした時点でコンストラクタが呼び出される。
・・用途
newでインスタンスを生成した時点で実行したい処理がある時に使う。
・・書き方
クラス名();
例
1 2 3 4 5 |
public class Hero(){ public void Hero(){ //コンストラクタ } } Hero h = new Hero(); //コンストラクタ発動!! |
・・特徴
オーバーロードで同じ名前のコンストラクタを複数定義できる。
this()で同一クラスの別コンストラクタを呼び出せる。
・・注意
全てのコンストラクタは先頭で親コンストラクタを呼び出さなければならない。
もしコンストラクタの先頭に super(); がないと自動で追加される。
・・よくあるエラー
子コンストラクタの先頭にsuper()がなければ、自動的にsuper();が追加される。
親コンストラクタに引数が必要な場合、エラーになる。
例
super(); ⇐自動で書かれた子のコンストラクタ
Hero(String name){} ⇐親のコンストラクタ(引数が必要)
public static void とは
・public
どのクラスからもアクセスできるということ
・void
戻り値なし
static(静的メンバ)とは
・・static
staticとは静的や固定という意味。
クラス特有の値やメソッドということ。
インスタンスではなく、クラスに実体が作られる。

・・staticつけるとどうなるの?
new でインスタンス生成しなくても使える。
逆にインスタンス毎の値を持てなくなる。
・・用途
各インスタンスに共通の値を持たせたい時に使う?
・例:RPGの3人パーティでHPは個別にしたいが、お金はパーティ共有にしたい場合。
Heroクラスにh1/h2/h3というインスタンス(3人パーティ)↓↓
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Hero{ int hp = 100; static int money = 1000; //staticなmoney public void Hero(){ Hero h1 = new Hero(); Hero h2 = new Hero(); Hero h3 = new Hero(); h1.hp = 20; //←hpは各インスタンスで別々 h2.hp = 40; //←hpは各インスタンスで別々 h3.hp = 70; //←hpは各インスタンスで別々 money = 500; //←moneyは全員共通(インスタンスではなくクラスが持っている) } } |
・・用途2
new しなくても使えるクラスのメソッドが欲しい時。
メインクラス
1 2 3 4 5 6 |
public class Main { public static void main(String[] args) { StaticTest.add(1, 2); } } |
StaticTestクラス
1 2 3 4 5 6 7 |
public class StaticTest { public static void add(int a, int b){ //メソッドにstaticを付ける。 int c = a + b; System.out.println(c); } } |
カプセル化
◆カプセル化とは
フィールドの変更やメソッドの呼び出しを制限するもの
◆用途
変数やクラスへのアクセスを制御したい時。
◆種類
private 自分自身のクラスのみ
何も書かない 自分と同じパッケージに属するクラスのみ
protected 自分と同じパッケージか、自分を継承した子クラス
public 全てのクラス
↑↑上にいくほど制限が厳しい
◆一般的な使い方
フィールドは全てprivate
メソッドはすべてpublic
クラスは全てpublic
基本は上記の通りにして、必要に応じて使い分けていく。
◆より安全にするために
setter/getterメソッドを使う
write only にしたりread onlyにしたりできる
setterの前にif文で妥当性チェックができる
getter/setterの例
1 2 3 4 5 6 7 8 9 |
praivate String name; public void setName(String name){ this.name = name; { public String getName(){ return this.name; } |
妥当性チェックの例
1 2 3 4 5 6 7 8 9 |
public class SetNameTest{ private String name; public void setName(String name){ if (name == "うんち"){ throw new IllegalArgumentException("不正な名前です。"); } this.name = name; } } |
継承
・・継承とは
親クラスのフィールドやメソッドを継承できる
・・継承方法
クラス名 extends 親クラス名{}
・・継承の関係
is-aの関係
A is-a B = 子クラスAは親クラスBの一種である
〇スーパーヒーローはヒーローの一種である
×家はアイテムの1種である。 家は持ち歩くアイテムではないので×。
・・汎化・特化の関係
親に行くほど汎用
子に行くほど特化
キャラクタークラス・親 ⇐ 勇者クラス・子 ⇐ 超勇者クラス・孫
・・特徴
同じメソッド名を親と子クラスに書くと親のメソッドを上書きできる。
finalクラスfinalメソッドは継承できない。
・・親クラスへのアクセス
super.メソッド名
super.フィールド名
super()
で親クラスを呼び出せる。
superは親まで、祖父母インスタンスまではアクセス不可能。
・・呼び出され方
一番下の子クラスから読み込まれ、なければ親クラスを読みに行く。
子クラスの中に親クラスが入っている感じ。
抽象クラス・抽象メソッド
・・抽象クラス(abstract)
・用途
継承用の抽象的なクラスを作っておきたい時。
・効果
new できないのでインスタンスとして使えない。
継承専用のクラスとなる。
・書き方
アクセス修飾子 abstract class クラス名{}
・例
public abstract class BattleJob{}
・・抽象メソッド(abstract)
・用途
将来確実に必要になるが、今は内容未確定の空メソッドを継承用に作っておきたい時。
・効果
このメソッドは未確定だから、ちゃんとオーバーライドしてね、という目印になる。
子クラスは抽象メソッドをオーバーライドしないとエラー出る。
抽象メソッドが一つでもあるクラスは抽象クラスにしないとエラー出る。
・書き方
アクセス修飾子 abstract 戻り値 メソッド名(引数);
・例
public abstract void attack (Matango m);
{} ⇐内容は空なので{}いらない
・特徴
{ }⇐の中身は書けない。
処理内容は未定ということ。
インターフェース
・・インターフェース
抽象的過ぎてほとんど中身がないクラスのこと。
・用途
大まかな型だけを決めたい時。(開発初期段階など)
・効果
子クラスは型通りの動きをするはず。
多重継承が可能。(子クラスが2つ以上のインターフェースを継承すること。)
・決まり事
メソッドは、abstractメソッド か default付メソッド しか持てない。
基本的にフィールドを持たない。
public static final(定数)がついたフィールドだけはOK。
ちなみにpublic static finalを省略しても勝手に補われる。
・書き方
アクセス修飾子 interface インターフェイス名{}
・例
public interface Human{}
・継承方法
インターフェースの継承には implements を使う。
インターフェースを継承して、中身を作ることを 実装 と言う。
・注意
インタフェースからインターフェースへの継承には extends を使う。
インターフェースからクラスの継承には implements を使う。
・extendとimplementsを同時に使うことも可能(多重継承)
書き方
アクセス修飾子 class クラス名 extends 親クラス
implements 親インターフェース1、親インターフェース2{}
例
public class Princess extends Character implements Human{}
オーバーライド
・・オーバーライドとは
スーパークラスのメソッドをサブクラスにおいて同じメソッド名で定義し直すこと
・・用途
すでに存在するクラスのメソッドを上書きして使いたい時。
・・特徴
「super」句を使うと、オーバーライドした場合でもスーパークラスで定義したメソッドを変更せずにそのまま使用することも可能。
・例
1 2 3 4 5 |
public class Monster{ public void run(){ System.out.println("モンスターは逃げ出した。"); } } |
1 2 3 4 5 |
public class Slime extends Monster{ public void run(){ System.out.println("スライムは逃げ出した。"); } } |
多態性
・・多態性とは
多態性はオブジェクト指向プログラミングを支える3代機能の1つで、ポリモーフィズムとも呼ばれる。
・・イメージ
あるものを、あえてざっくり捉えることで、様々なメリットを享受しようという機能。
たぶん、インスタンス1つ1つに指示をだすのは面倒なので、親クラスに指示したら子クラスが一斉に動くようにしようみたいな感じ。


・・特徴
親クラス型の配列に子インスタンスを格納できる。
親クラスの型変数に子インスタンスを代入できる。
・例
Character c = new Wizard();
・・用途
複数の同種のインスタンスにまとめて指示を出したい時。
・例
Monster型のインスタンスにまとめてrun();
1 2 3 4 5 6 7 8 |
Monster[] monsters = new Monster[3]; monsters[0] = new Slime(); monsters[1] = new Goblin(); monsters[2] = new DeathBat(); for(Monster m : monsters){ m.run(); } |
実行結果
スライムは逃げ出した。
ゴブリンは逃げ出した。
デス蝙蝠は逃げ出した。
・・注意
親の型に入った子インスタンスは、子独自のメソッドを使えなくなる。
オーバーライドされていれば子クラスメソッドも使える。
・例
Monster型のMonsterインスタンスと
Monster型のSlimeインスタンスを生成してみる。
Monsterクラス
1 2 3 4 5 |
public class Monster{ public void run(){ System.out.println("モンスターは逃げ出した。"); } } |
Slimeクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Slime extends Monster{ public void run(){ System.out.println("スライムは逃げ出した。"); } } Slime s = new Slime(); Monster m = new Slime(); Monster n = new Monster(); s.run(); //⇐スライムは逃げ出した m.run(); //⇐スライムは逃げ出した n.run(); //⇐モンスターは逃げ出した |
実行結果
スライムは逃げ出した。
スライムは逃げ出した。
モンスターは逃げ出した。
・・instance of 演算子
変数 instanceof 型名 で型を変更可能かチェックできる。
・例:スーパーヒーロー型変数hに別の型の変数cを代入。
1 2 3 |
if (c instanceof SuperHero){ SuperHero h = (SuperHero) c; } |
API:日付の取得
・現在日時の取得
Date型
1 |
Date now = new Date(); |
Date型の使用は今では非推奨らしいです。
新しく「Date and Time API}というのが出ています。
long型
1 2 |
long now2 = System.currentTimeMillis(); System.out.println(now2); |
Calendar型
1 2 |
Calendar c = Calendar.getInstance(); System.out.println(c.getTime()); |
String型
1 2 3 |
Calendar c = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); System.out.println(sdf.format(c.getTime())); |
6つのint型(6つのint変数に分けて格納・年、月、日、時、分、秒)
1 2 3 4 5 6 7 8 9 |
Calendar cl2 = Calendar.getInstance(); cl2.setTime(cl2.getTime()); int year = cl2.get(Calendar.YEAR) int month = cl2.get(Calendar.MONTH) //月は1~12でなく、0~11なので1ヶ月ずれる。 int day = cl2.get(Calendar.DATE) int hour = cl2.get(Calendar.HOUR) int minute = cl2.get(Calendar.MINUTE) int second = cl2.get(Calendar.SECOND) |
Calendarインスタンス生成 → 日付をCalendarで取得 → Calendarにセット →Calendarからゲットしてint変数に代入という流れ。
例外処理
・・例外処理とは
実行時エラーの対応策。
あらかじめエラーが発生した時の対応策を記述しておき、事態を回避する。
・例
IOEception(ファイルの読み書きができない)
ConnectException(ネットワークに接続できない)
・・書き方
try {実行内容} catch (Exception e) {エラー時の実行内容}
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void Test(){ try{ FileWriter fw = new FileWriter("data.txt"); fw.write("hello"); }catch (IOException e) { Systemu.out.println("エラーです"); }finally{ fw.close(); } } |
・・finallyとは
例外が発生しようしまいが必ず処理を実行する。
・用途
エラー発生時でも必ず行わなければならない処理がある時。
・例
ファイルを閉じる、ネットワークを切断する等。
・・throwとは
例外発生しても処理せず、メソッドの呼び出し元に処理を委ねる。
・用途
???
・特徴
呼び出し元はtry catch文で処理する必要がある。
・書き方
1 |
public void Test () throws IOExeption { } |
catch文は書かない。
・・throwの別の使い方
例外をJVMに投げる
・用途
独自のルールを設けたい時
・書き方
throw new 例外クラス名(エラーメッセージ)
・例
1 |
throw new IllegalArgumentException("名前は1文字以上に設定してください"); |
・・例外クラスは大きく3つ
Error系
Exception系
RuntimeException系
まとめ
オブジェクト指向が本書のメインと感じました。
オブジェクト指向は概念的なもので理解が難しいですが、これからもJavaに触れつつじっくりと理解していこうと思います。