スッキリわかるJava入門(入門編)でプログラミングを始める

スタート地点
　①ProgateでHTML/CSSを修了後、Javaに挑戦(メソッド、クラスまでやり、理解が不十分）
　②Udemyの動画を参考にandroidstudioでアプリ作成を試みるもよくわからなく挫折
　③何かを作るためにJavaの基礎を一通り覚えたいと考え、入門書で四則演算や文字の入力、出力まで学習
　④学習した内容のアウトプットを開始←ココからスタート

# 第3章　条件分岐と繰り返し
----------------------------------------------

####リスト３−１　天気による行動の変化の行動【if文】
----------------------------------------------

```java
   public class Main{
     public static void main(String[] args){
       boolean tenki = true;
       if (tenki == true){
         System.out.println("洗濯");
         System.out.println("散歩");
       } else {
         System.out.println("DVDを見る");
       }
     }
    }
```
+++++++++++++++++++++++++++実行結果++
   洗濯
   散歩
++++++++++++++++++++++++++++++++++++
　if文はエクセルの関数とかと考え方が同じような感じがするので理解しやすい。
elseのあとにifを書いてさらに条件式を加えることが可能。


####リスト３−２　トイレの空き時間を待つ繰り返し処理【while】
----------------------------------------------
```java

public class Main {
  public static void main(String[] args) {
    boolean doorClose = true;     
    while(doorClose == true) {      //このブロックではdoorCloseがtrueの場合無限ループになる
      System.out.println("ノックする");  
      System.out.println("1分待つ");
    }
      System.out.println("トイレに入る");//doorCloseがfalseの場合ループを抜けてこちらが実行される
  }    
}     
```
　while（条件式）｛条件式がtrueの間この中の処理をループさせる｝
っていう理解で良いのかな。
　
　ifやwhileは制御構文と言う。
　制御構文の特徴
　　①条件式がある
　　②ブロック（｛｝で囲む処理のあつまり）がある

　ちなみにブロックには以下２つのルールがあるらしい。
　　①ブロック内が１行であれば｛｝を省略可能
　　②ブロック内で宣言した変数はブロック外で使用できない（変数を利用できる範囲＝スコープという）
　①の｛｝省略は推奨されていないという。なのになぜこんなルールがあるのか・・・
　スコープは覚えておこう。
　
####【do-while】
----------------------------------------------
　基本的なwhile文は条件式を評価してブロックが実行されるが、whileの前にdo｛｝を書くとdoのブロックを実行後に条件式を評価してtrueならループする。

```java

public class Main {
  public static void main(String[] args) {
    boolean doorClose = true;  
    do { 
     System.out.println("トイレに入る");
    }
    while(doorClose == true);
  }    
} 
```
　上の式だと、”トイレに入る”を出力してからwhile文のループに入る。


####リスト３−６　占い文【switch】
----------------------------------------------
```java

public class Main {
  public static void main(String[] args) {
    System.out.println("あなたの運勢を占います");
    int fortune = 1;    //常に1 
    switch(fortune) {
      case 1:
        System.out.println("大吉");
        break;
      case 2:
        System.out.println("中吉");
        break;
      case 3:
        System.out.println("吉");
        break;
      default:
        System.out.println("凶");
    }
  }
}
```
+++++++++++++++++++++++++++実行結果++
   あなたの運勢を占います
　　大吉
++++++++++++++++++++++++++++++++++++
　　
　　条件式に当てはまるcaseラベルが実行される。
　　break；を忘れると次のラベルの処理も実行される。例えばcase１のbreak；を消すと、
　　fortuneが１の場合、大吉と中吉が両方表示される。


####リスト３−７　基本的なfor分のサンプル【for】

```java

public class Main {
  public static void main(String[] args) {
    for(int i = 0; i < 10; i++) {
      System.out.println("こんにちは");
    }
  }
}
```
+++++++++++++++++++++++++++実行結果++
　　こんにちは
　　　｜｜こんにちはが１０回表示される
　　こんにちは
++++++++++++++++++++++++++++++++++++
　for(int i = 0; i < 10; i++)がミソ
　　　①int i = 0
　　　　整数型の変数iを初期化
　　　②i < 10
　　　　１０のところに繰り返したい回数を入れる
　　　③i++
　　　　変数iに１を足す（for文のブロック実行後に自動的に実行される文）
　
　for文のバリエーション
　　　●for(int i = 1; i < 10; i++){}
      ループを１からスタート
     ●for(int i = 0; i < 10; i+=2){}
　　　 ループ変数を２ずつ増やす
     ●for(int i = 10; i > 0; i--){}
      ループ変数を１０から１ずつ減らす
     ●for(; i < 10; i++){}
      ループ変数を初期化しない
     ●for(int i = 1; i < 10){}
      繰り返し時の処理を行わない


####制御構造のネスト（入れ子）
----------------------------------------------
####リスト３−９　for文のループを２重にして九九の表を出力
----------------------------------------------

```java

public class Main {
  public static void main(String[] args) {
    for (int w = 1; w < 10; w++){
      for (int h = 1; h < 10; h++){
        System.out.print(w * h + " ");
      }
      System.out.println("");
    }
  }
}
```
+++++++++++++++++++++++++++実行結果++
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
++++++++++++++++++++++++++++++++++++
  実行の流れを整理してみると
　１．【１の段】
　　①ループ変数ｗのfor文の中のループ変数ｈのfor文の中の処理の実行
　　　ループ変数はどちらとも初期値１なので１＊１を出力（改行なし）
　　　このあとｈに１がプラスされる
　　②ループ変数hのfor文２周目
　　　ｈは２となったので１＊２を出力（改行なし）
　　　このあとｈに１がプラスされる
　　③ループ変数hのfor文３周目
　　　ｈは３となったので１＊３を出力（改行なし）
　　　このあとｈに１がプラスされる
　　④ループ変数ｈのfor文をh＝９まで繰り返す（１の段が完成）
　　⑤ループ変数ｗの処理である改行を出力
　　　このあとｗに１がプラスされる
　２．【２の段】
　　①ループ変数ｗのfor文の中のループ変数ｈのfor文の中の処理の実行
　　　ループ変数ｗは２、ループ変数ｈは初期化されるので２＊１を出力（改行なし）
　　　このあとｈに１がプラスされる
　　②ループ変数hのfor文２周目
　　　ｈは２となったので２＊２を出力（改行なし）
　　　このあとｈに１がプラスされる
　　③ループ変数hのfor文３周目
　　　ｈは３となったので２＊３を出力（改行なし）
　　　このあとｈに１がプラスされる
　　④ループ変数ｈのfor文をh＝９まで繰り返す（２の段が完成）
　　⑤ループ変数ｗの処理である改行を出力
　　　このあとｗに１がプラスされる
　上記をループ変数ｗ＝９まで繰り返して処理を抜ける。

　書いてはみたが、この流れを後で見返した時に理解できるものなのか不安。


####【break】と【continue】
----------------------------------------------
####【break】

```java
   for (int i = 1; i < 10; i++){
    if(i == 3){
    break;
    }
    System.out.println(i);
   }
   //breakの場合はi == 3の時点で繰り返し処理を中断。
```

####【continue】
```java
   for (int i = 1; i < 10; i++){
    if(i == 3){
    continue;
    }
    System.out.println(i);
   }
   //continueの場合はi == 3の時点で一度繰り返し処理を中断し、次の週から繰り返しを再開する。
```
####３章の練習問題
----------------------------------------------
####練習３−１
  ①if(weight == 60)
  ②if((age1 + age2)* 2 > 60)
  ③if(age % 2 != 0)
  ④if(name.equals("湊"))

####練習３−３
```java
    int seibetsu = 0;
    int age = 25;
      System.out.println("こんにちは。");
      if(seibetsu == 0){
      System.out.println("私は男です。");
      System.out.println(age + "歳です。");
    }else{
     System.out.println("私は女です。");
     }
     System.out.println("よろしくおねがいします。");
```
+++++++++++++++++++++++++++実行結果++
  こんにちは。
  私は男です。
  25歳です。
  よろしくおねがいします。
++++++++++++++++++++++++++++++++++++

####練習３−５

```java

  ①System.out.println("[メニュー]：1:検索2:登録3:削除4:変更>]");
  ②int selected = new java.util.Scanner(System.in).nextInt();
  ③switch(selected){
    case 1:
     System.out.println("検索します"); 
    break;
    case 2:
     System.out.println("登録します");
    break;
    case 3:
     System.out.println("削除します");
    break;
    case 4:
     System.out.println("変更します");
    break;
    }
```

+++++++++++++++++++++++++++実行結果++
  [メニュー]：1:検索2:登録3:削除4:変更>]
  検索します
++++++++++++++++++++++++++++++++++++

####練習３−６
```java
    System.out.println("【数あてゲーム】");
    int ans = new java.util.Random().nextInt(9);
    for(int i = 0; i < 5; i++){
      System.out.println("０〜９の数字を入力してください");
      int num = new java.util.Scanner(System.in).nextInt();
      if (num == ans){
        System.out.println("アタリ！");
        break;
      }else{
        System.out.println("違います。");
       }
    }
    System.out.println("ゲームを修了します");
 ```
+++++++++++++++++++++++++++実行結果++
 〜あたった場合〜
　【数あてゲーム】
　０〜９の数字を入力してください
　違います。
　０〜９の数字を入力してください
　アタリ！
　ゲームを修了します
++++++++++++++++++++++++++++++++++++
〜あたらなかった場合〜
　【数あてゲーム】
　０〜９の数字を入力してください
　違います。
　０〜９の数字を入力してください
　違います。
　０〜９の数字を入力してください
　違います。
　０〜９の数字を入力してください
　違います。
　０〜９の数字を入力してください
　違います。
　ゲームを修了します
++++++++++++++++++++++++++++++++++++


#第4章　配列
----------------------------------------------
配列の作成と代入
  基本形  

```java
  int[] score;
  score = new int[5];
```
  省略記法

```java
  /*①*/int[] score = new int[] {20, 30, 40, 50, 80};
  /*②*/int[] score = {20, 30, 40, 50, 80};
```
  配列を回す

```java
  public class Main {
  public static void main(String[] args) {
    int[] score = { 20, 30, 40, 50, 80 };
    for(int i = 0; i < score.length; i++) {    // 配列名.lengthで要素数を得る
      System.out.println(score[i]);            // 要素を指定してとりだす必要がある
    }
  }
}
```
  配列を回す（拡張for文）

```java
  public class Main {
  public static void main(String[] args) {
    int[] score = { 20, 30, 40, 50, 80 };
    for(int value : score) {      // ループが1周するたびに次の要素がvalueに入る
      System.out.println(value);  // valueをそのまま使える
    }
  }
}
```

####【配列の参照の仕組み】

```java
public class Main {
  public static void main(String[] args) {
/*①*/int[] a = { 1, 2, 3 };
/*②*/int[] b;
       b = a;
/*③*/b[0] = 100;
/*④*/System.out.println(a[0]);
  }
}
```
+++++++++++++++++++++++++++実行結果++
　１００
++++++++++++++++++++++++++++++++++++
上記のプログラムでは
　　　①aの配列変数にそれぞれ１，２，３を代入
　　　②ｂの配列を作成後、ｂにaを代入
　　　③その後、ｂの要素０に１００を代入
　　　④aの要素０を出力
という流れである。配列は「参照型」といい、メモリ上の番地を参照しているため、
配列変数ｂにaを代入した段階でa及びbの要素はメモリ上の同じ番地を参照している事となる。
なので、③でbの要素０に１００を代入すると、ｂの要素はaの要素と同じ場所にあるので、aの要素０の中身も１００となる。



####【length】
lengthを使うと、配列の文字数だけでなく
文字列変数の文字数も得ることができる。

```java
String s = "java";
System.out.println(s.length());  //文字列変数に対して使用するときは（）が必要！
```
+++++++++++++++++++++++++++実行結果++
　4
++++++++++++++++++++++++++++++++++++

####多次元配列
----------------------------------------------
####【２次元配列の宣言】
 要素の型[][]　配列変数名= new 要素の型[行数][列数];
　
####【２次元配列の要素の利用】
 配列変数名[行の添字][列の添字]

####【２次元配列：兄弟２人の３科目のテストの点数】

```java
public class Main {
 public static void main(String[] args) {
   int[][] scores = new int[2][3];   //またはint[][] scores = {{40,50,60},{80,60,70}};
   scores[0][0] = 40;
   scores[0][1] = 50;
   scores[0][2] = 60;
   scores[1][0] = 80;
   scores[1][1] = 60;
   scores[1][2] = 70;
   System.out.println(scores[1][1]);
  }
}
```
+++++++++++++++++++++++++++実行結果++
　６０
++++++++++++++++++++++++++++++++++++
上記配列のイメージ
　　　[40][50][60]
　　　[80][60][70]


####４章の練習問題
----------------------------------------------
####練習４−１

```java
 int[] pints = new int[4];
 double[] wights = new double[5];
 boolean[] answers = new boolean[3];
 String[] names = new String[3];
```
####練習４-２

```java
public class Main { 
  public static void main(String[] args){
    int[] moneyList = {121902, 8302, 55100};
    for (int i = 0; i < 3; i++){
    System.out.println(moneyList[i]);
    }
    for(int value : moneyList){
    System.out.println(value);
    }
  }
}
```
+++++++++++++++++++++++++++実行結果++
  121902
  8302
  55100
  121902
  8302
  55100
+++++++++++++++++++++++++++++++++++

####練習４−３

```java
public class Main {
  public static void main(String[] args){
    int [] numbers = {3, 4, 9};
    System.out.println("「１桁の数字を入力してください」");
    int input = new java.util.Scanner(System.in).nextInt();
    for (int value: numbers){
    if (input == value){
       System.out.println("アタリ！");
    }
    }
  }
}
```
+++++++++++++++++++++++++++実行結果++
  「１桁の数字を入力してください」
  アタリ！　//数字の３，４，９を入力した場合。
++++++++++++++++++++++++++++++++++++


#第5章　メソッド
----------------------------------------------
####【メソッドの定義】

```java:メソッドの定義
      public static /*戻り値の型  メソッド名 (引数リスト)*/ {
        //メソッドが呼び出されたときに実行される具体的な処理
      }

      //例
      public static void hello() {
        System.out.println("こんにちは");
      }
```
####【メソッドの呼び出し】

```java:メソッドの呼び出し
      //メソッド名(引数リスト);

      //例　　　（helloメソッドの呼び出し）
      public class Main{
        public static void main(String[] args){
          System.out.println("メソッドを呼び出します");
          hello();
          System.out.println("メソッドの呼び出しがおわりました");
        }
        public static void hello() {
          System.out.println("こんにちは");
        }
      }
```
+++++++++++++++++++++++++++実行結果++
  メソッドを呼び出します
  こんにちは
  メソッドの呼び出しがおわりました
++++++++++++++++++++++++++++++++++++
※メソッドがいくつ定義されていても、main()より上に別メソッドが定義されていても、
 プログラムは必ずmain()から動き始める

###【引数の利用】
######【引数を１つ渡す例】
```java:引数を１つ渡す例
  
      public class Main{
        public static void main(String[] args){
          System.out.println("メソッドを呼び出します");
          hello("湊");     //引数は湊
          hello("朝香");   //引数は朝香
          hello("菅原");   //引数は菅原
          System.out.println("メソッドの呼び出しがおわりました");
        }
        public static void hello(String/*引数の型*/ name/*受け取る引数が入る変数名*/) {
          System.out.println(name + "さん、こんにちは");
        }
      }
```
+++++++++++++++++++++++++++実行結果++
  メソッドを呼び出します
  湊さん、こんにちは
  朝香さん、こんにちは
  菅原さん、こんにちは
  メソッドの呼び出しがおわりました
++++++++++++++++++++++++++++++++++++
######【引数を複数渡す例】
```java:引数を複数渡す例
      
      public class Main{
        public static void main(String[] args){
        add(100, 20);     //引数は100と20
        add(200, 50);     //引数は200と50
        }

        //複数の値を受け取るaddメソッド
        public static void add(int/*引数の型*/ x/*受け取る引数が入る変数名*/,
                               int/*2つめの引数の型*/ y/*２つ目の引数が入る変数名*/) {
          int ans = x + y;
          System.out.println(x + "+" + y + "=" + ans);
        }
      }
```
+++++++++++++++++++++++++++実行結果++
  100+20=120
  200+50=250
++++++++++++++++++++++++++++++++++++
※渡す引数（**実引数**）と受け取る変数（**仮引数**）の方が一致しない場合はコンパイルエラーとなる。

###【return】
######【値の戻し方】
 **public　static　戻り値の型　メソッド名(引数リスト){
   メソッドが実行されたときに動く処理
   return　戻り値;
   }**

######【メソッドを呼び出し、戻り値を受け取る】
 **型　変数名　=　メソッド名(引数リスト);**

※文に=（代入演算子）があるため、右辺（メソッドの呼び出し）から評価され、
 評価されて戻ってきた値に置き換わる
 結果として、左辺の変数に戻り地が代入される

######【戻り値の例】
```java:戻り値の例
      
      public class Main{
        public static int add(int x, int y){
          int ans = x + y;
          return ans/*戻り値*/;
        }
        public static void main(String[] args){
          int and = add(100, 10)/*右辺が戻り値(ans)に置き換わる*/;
          System.out.println("100 + 10 = "  + ans);
        }
      }
```

+++++++++++++++++++++++++++実行結果++
  100 + 10 = 110
++++++++++++++++++++++++++++++++++++

######【戻り値をそのまま使う】
```java:戻り値をそのまま使う
      
      public class Main{
        public static int add(int x, int y){
          int ans = x + y;
          return ans/*戻り値*/;
        }
        public static void main(String[] args){
          System.out.println(add(add(10, 20), add(30, 40)));
                  //①addメソッドの実引数（10, 20)が３０に置き換わる
                  //②addメソッドの実引数（３0, ４0)が７０に置き換わる
                  //③addメソッドの実引数（①30, ②70)が１００に置き換わる
        }
      }
```

+++++++++++++++++++++++++++実行結果++
  １００
++++++++++++++++++++++++++++++++++++
※return文はメソッドを終了させるため、
 return文の後に書かれた処理は実行されないことに注意する

######【オーバーロード】
　基本的に同じメソッド名をつけることはできないが、仮引数の個数か型が異なれば同じ名前のメソッドを複数定義することができる。

######【引数や戻り値に配列を用いる】
######【戻り値をそのまま使う引数や戻り値に配列を用いる】
```java:戻り値をそのまま使う
      
      public class Main {
	// int型配列を受け取り、すべての要素を表示するメソッド
        public static void printArray(int[] array) {
          for( int element : array ){
            System.out.println(element);
          }
        }
        public static void main(String[] args){
          int[] array = {1,2,3};
          printArray(array);	// 配列を渡す
        }
      }
```
+++++++++++++++++++++++++++実行結果++
  1
  2
  3
++++++++++++++++++++++++++++++++++++

######【戻り値に配列を用いる】
```java:戻り値に配列を用いる
      
      public class Main {
        public static int[] makeArray(int size/*②①によりsizeに３を代入*/) {
          int[] newArray = new int[size]; //③配列変数newArrayに３つの要素を代入
          for( int i = 0; i < newArray.length; i++ ){ //④③newArrayの配列数分なので３回繰り返す
            newArray[i] = i;　//※繰り返される処理　⑤newArray[0]に０を代入、newArray[１]に１を代入、newArray[２]に２を代入
          }
          return newArray;　//⑥配列変数newArray{0, 1, 2}を返す
        }
        public static void main(String[] args){
          int[] array = makeArray(3)/*①makeArrayメソッドに実引数３を渡して呼び出す結果を配列変数ａｒｒａｙに代入*/;
          for(int i : array) { //⑥配列変数arrayを回す
            System.out.println(i);※繰り返される処理　⑦0, 1, 2を出力
          }
        }
      }
```
+++++++++++++++++++++++++++実行結果++
  ０
  1
  2
++++++++++++++++++++++++++++++++++++

######【コマンドライン引数】
**public　static　void　main(String[]　args){**

mainメソッドは文字列配列を引数として受け取るように定義されていて、
javaコマンドを使ってプログラムを実行する際に、プログラム名の後ろに引数を指定することができる。

```terminal:ターミナル
  パソコン名:~ ユーザー名$ java プログラム名 引数リスト（半角スペース区切り）
```
```terminal:ターミナル：コマンドライン引数の例
  パソコン名:~ ユーザー名$ java main 菅原 湊 朝香
```
上記の例でプログラムを実行した場合、mainメソッドのargs[0]には「菅原」、args[1]には「湊」、args[2]には「朝香」が格納され、args.lengthは３となる。

######【５章の練習問題】
```java:練習５−１〜５-４
public class Main { 
  public static void main(String[] args){
    introduceOneself();
    email("タイトル","test@gmail.com","テスト１");
    email("test@gmail.com", "テスト２");
    System.out.println("三角形の底辺の長さが10.0cm、高さが5.0cmの場合、面積は" + calcTriangleArea(10.0, 5.0) + "cm2");
    System.out.println("円の半径が5.0cmの場合、面積は" + calcCircleArea(5.0) + "cm2");
  }

  public static void introduceOneself(){
    String name = "name";
    int age = 25;
    double height = 160;
    char gender = '男';
    System.out.println("私の名前は" + name + "です。年齢は" + age + "歳です。身長は" + height + "cmです。性別は" + gender + "です。" );
  }

  public static void email(String title, String address, String text){
    System.out.println("「" + address + "」に、以下のメールを送信しました");
    System.out.println("件名：「" + title + "」");
    System.out.println("本文：「" + text + "」");
  }   

  public static void email(String address, String text){
    System.out.println("「" + address + "」に、以下のメールを送信しました");
    System.out.println("件名：無題");
    System.out.println("本文：「" + text + "」");
  }

  public static double calcTriangleArea(double bottom, double height){
    double ans = bottom * height / 2;
    return ans;
  }

  public static double calcCircleArea(double radius){
    double ans = radius * radius * 3.14;
    return ans;
  }
}
```
+++++++++++++++++++++++++++実行結果++
  私の名前はnameです。年齢は25歳です。身長は160.0cmです。性別は男です。
  「test@gmail.com」に、以下のメールを送信しました
  件名：「タイトル」
  本文：「テスト１」
  「test@gmail.com」に、以下のメールを送信しました
  件名：無題
  本文：「テスト２」
  三角形の底辺の長さが10.0cm、高さが5.0cmの場合、面積は25.0cm2
  円の半径が5.0cmの場合、面積は78.5cm2
++++++++++++++++++++++++++++++++++++



#付録Ａ　ＪＤＫを用いた開発
----------------------------------------------
ＪＤＫのダウンロード及びインストールが終了したので
iTermでHello world!を表示させる。

①テキストエディタで以下のテキストを作成
　ファイルの場所：Users/ユーザー名/Desktop/Java\ \ source\ codes/Java\ source\ no.1
　ファイル名：Main.java
　コード：

```java:Main.java
      public class Main {
        public static void main(String[] args){
          System.out.println("Hello World!");
        }
      }
```
②iTermを起動
　・ｃｄ　/Users/ユーザー名/Desktop/Java\ \ source\ codes/Java\ source\ no.1
　ファイル名：Main.javaを実行
　・lsを実行
　 →Main.java　と表示される。
　・javac Main.javaを実行　【コンパイル】
　・lsを実行
　 →Main.class	Main.java　と表示される。　【Main.classの作成を確認】
　・java Main.java 【Javaの実行】
　 →Hello world!と表示される。

#第6章　複数クラスを用いた開発
----------------------------------------------
　計算プログラムを以下のように
　・出力担当
　・計算担当
　の２つに分割

```java:Calc.java
  public class Calc{
    public static void main(String[] args) {
        int a = 10;
        int b = 2;
        int total = CalcLogic.tasu(a, b);
        int delta = CalcLogic.hiku(a, b);
        System.out.println("足すと" + total + "、引くと" + delta);
    }
  }
```
```java:CalcLogic.java
  public class CalcLogic{
    public static int tasu(int a, int b){
        return (a + b);
    }
    public static int hiku(int a, int b){
        return (a - b);
    }
  }
```

```terminal:ターミナル
  パソコン名:~ ユーザー名$ cd /Users/ユーザー名/Desktop/Java\ \ source\ codes/Java\ 
  source\ no.2
  パソコン名:Java source no.2 ユーザー名$ ls
  Calc.java	CalcLogic.java
  パソコン名:Java source no.2 ユーザー名$ javac Calc.java CalcLogic.java　【２つともコンパイル】
  パソコン名:Java source no.2 ユーザー名$ ls
  Calc.class	Calc.java	CalcLogic.class	CalcLogic.java　【classファイルの作成を確認】
  パソコン名:Java source no.2 ユーザー名$ java Calc　【mainクラスがあるファイルを実行する】
  足すと12、引くと8　【結果】
```
上記のように、Javaのプログラムを実行するためには、mainメソッドが含まれているクラスファイルを指定する必要がある。
このため複数の完成クラスファイルを配布・納品するときには、すべてのクラスファイルを渡すのとあわせて、どのクラスにmainメソッドが含まれているかを伝える必要がある。

クラスが膨大な数になった場合、コンパイルの際に一つずつクラス名を入力するのは不可能そうだが、どういう方法があるのだろう。

####パッケージの利用
----------------------------------------------
クラス数が増えた場合、各クラスをパッケージ（package）と言うグループにまとめて管理・分類することが可能。
####【package】
  package 所属させたいパッケージ名;
※パッケージ文はソースコードの先頭に記載する必要がある。

####【パッケージを呼び出す時(ＦＱＣＮ)】
  あるクラスから別パッケージのクラスを利用する場合、下記のように、パッケージ名を頭につけた完全なクラス名を指定する必要がある。
  完全なクラス名(ＦＱＣＮ)
　パッケージ名.クラス名

先程の計算プログラムをそれぞれパッケージに所属させる場合

```java:Calc.java
  package calcapp.main; //所属パッケージ名を指定
  public class Calc{
    public static void main(String[] args) {
        int a = 10;
        int b = 2;
        int total = calcapp.logics.CalcLogic.tasu(a, b);
         //クラスを呼び出すときにも、パッケージ名を頭につけた完全なクラス名(FQCN)の指定が必要
        int delta = calcapp.logics.CalcLogic.hiku(a, b);
         //クラスを呼び出すときにも、パッケージ名を頭につけた完全なクラス名(FQCN)の指定が必要
        System.out.println("足すと" + total + "、引くと" + delta);
    }
  }
```
```java:CalcLogic.java
  package calcapp.logics; //所属パッケージ名を指定
  public class CalcLogic{
    public static int tasu(int a, int b){
        return (a + b);
    }
    public static int hiku(int a, int b){
        return (a - b);
    }
  }
```
####推奨されるパッケージ名
パッケージ名の重複を避けるため、パッケージ名は
「保有するインターネットドメインを前後逆順にしたもの」
から始める。
例　ドメイン名：foo.example.com
 パッケージ名：com.example.fooから始める

####【import】
パッケージ名の入力を省略する方法

```java:Calc.java
  package calcapp.main;
  import calcapp.logics.CalcLogic;
   //CalcLogicという表記があったら、calcapp.logics.CalcLogicと解釈せよの意
  import calcapp.logics.*;
   //calcapp.logics内のすべてのクラスを一度にインポートするには上記の書き方も使える
  public class Calc{
    public static void main(String[] args) {
        int a = 10;
        int b = 2;
        int total = CalcLogic.tasu(a, b);
         //FQCNでなくてもエラーにならない
        int delta = calcapp.logics.CalcLogic.hiku(a, b);
         //FQCNで記述しても良い
        System.out.println("足すと" + total + "、引くと" + delta);
    }
  }
```

####クラスファイルを探す仕組み
　Javaでは、使用したいクラスは、使用するときに、都度読み込まれるが、クラスファイルがどのフォルダにあるかということは指定しなくても実行ができるが、以下の方法でクラスファイルの場所として読み込みに行くべきフォルダの場所（クラスパス）を指定する事ができる。

　【方法１：起動時にｊａｖａコマンドで指定】　(/var/javadevをクラスパスとする場合)

```terminal:ターミナル
  パソコン名:~ ユーザー名$ javac -classpath /var/javadev
```
　【方法２：検索場所をOSに登録しておく】　(/var/javadevをクラスパスとする場合)

```terminal:ターミナル
  パソコン名:~ ユーザー名$ export CLASSPATH =/var/javadev
```
　なお、複数のクラスパスを指定する場合、macでは下記のように：（コロン）でつなぐ。

```terminal:ターミナル
  パソコン名:~ ユーザー名$ javac -classpath /var/javadev:/var/javadev2
```
　【方法３：特に指定しない】
　-classpathオプションの指定や、OSにクラスパスの指定をしなかった場合は、
　javaコマンドが実行されたフォルダがクラスパスとなる。
　→作成したプログラムが上手く起動できない場合は、クラスパスを確認する。
　　

　【クラスパスの指定について参考にしたわかりやすい記事】
　http://kuwwta.hatenablog.com/entry/2016/05/12/141246

####練習６−１

```java:Main.java
  import comment.Zenhan;
  public class Main { 
    public static void main(String[] args) throws Exception{
      Zenhan.doWarusa();
      Zenhan.doTogame();
      comment.Kouhan.callDeae();
      comment.Kouhan.showMondokoro();
    }
  }
```

```java:Zenhan.java
  package comment;
  public class Zenhan { 
    public static void doWarusa() {
      System.out.println("きなこでござる。食えませんがの。");
    }
    public static void doTogame() {
      System.out.println("この老いぼれの目はごまかせませんぞ");
    }
  }
```

```java:Kouhan.java
  package comment;
  public class Kouhan { 
    public static void callDeae() {
      System.out.println("えぇい、こしゃくな。くせ者だ！であえい！");
    }
    public static void showMondokoro() throws Exception {
      System.out.println("飛車さん、角さん。もういいでしょう。");
      System.out.println("この紋所が目にはいらぬか！");
      Thread.sleep(3000);  //【練習６−３】
      comment.Zenhan.doTogame();
    }
  }
```
####練習６−２

```terminal:ターミナル(正常動作時)
パソコン名:~ ユーザー名$ cd /Users/ユーザー名/Desktop/Java\ \ source\ codes/Java\ source\ no.3
パソコン名:~ ユーザー名$ ls
Main.java	comment
パソコン名:~ ユーザー名$javac Main.java Zenhan.java Kouhan.java
パソコン名:~ ユーザー名$ ls
Main.java	comment
パソコン名:~ ユーザー名$ javac Main.java comment/Zenhan.java comment/Kouhan.java
パソコン名:~ ユーザー名$ ls
Main.class	Main.java	comment
パソコン名:~ ユーザー名$ java Main
きなこでござる。食えませんがの。
この老いぼれの目はごまかせませんぞ
えぇい、こしゃくな。くせ者だ！であえい！
飛車さん、角さん。もういいでしょう。
この紋所が目にはいらぬか！
この老いぼれの目はごまかせませんぞ
```

６−１で、ソースコードを３分割にするのは比較的すぐできたが、実際にプログラムを実行するまでにとても時間がかかった。
コンパイルは難なくできたが、javaコマンドを実行すると、下記のエラーが出て、お手上げであった。
　

```terminal:ターミナル（エラー時）
パソコン名:~ ユーザー名$ javac Kouhan.java Main.java Zenhan.java
パソコン名:~ ユーザー名$ ls
Kouhan.class	Main.class	Zenhan.class
Kouhan.java	Main.java	Zenhan.java
パソコン名:~ ユーザー名$ java Main
Exception in thread "main" java.lang.NoClassDefFoundError: comment/Zenhan
	at Main.main(Main.java:4)
Caused by: java.lang.ClassNotFoundException: comment.Zenhan
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	... 1 more
```

①エラーを頑張って読んでみる→よくわからなかった。
②エラーをコピペしてググる→同じ練習問題で躓いてる人が質問サイトで質問していたが、解決せず。
③第15章：例外を読んでみる→3つのエラーの種類があるところまでしか理解できず。
④練習問題の少し前を読み返すと、解説が書いてあり、解決。
解決まで１週間ほどかかってしまった。

####パッケージに属したクラスの実行方法
【javaコマンドの正確な構文】
　>java 起動したいクラスの**完全限定クラス名(ＦＱＣＮ)**
【クラスファイルの正しい配置】
　今回のケース、commentパッケージに属するZenhanクラス及びKouhanクラスを実行するためには、
　Mainクラスと同じ階層にcommentディレクトリを作成し、その中にZenhanクラス及びKouhanクラスを格納すると実行ができた。
　つまり、パッケージ名のディレクトリの中に、そのパッケージに属するクラスファイルを保存しておく必要があった。

####練習６−３
練習６−１のコード内

####練習６−４
①c:¥work¥ex64の中にMain.classを配置
②c:¥work¥ex64¥commentの中にZenhan.class及びKouhan.classを配置

####練習６−５
c:¥javaapp¥koumon

####javaとjavacについて
javac実行時→.javaをつけて入力
　　　「どのソースをコンパイルするか」を**ファイル名で指定**して実行するため
java 実行時→拡張子は不要
　　　「どのクラスのmainメソッドを起動するか」を**クラス名(ＦＱＣＮ)で指定**して実行するため

#第7章　オブジェクト指向をはじめよう
----------------------------------------------
　オブジェクト指向は、「人間が把握しきれない複雑さ」を克服するために生まれた。
そもそもプログラムやシステムは**現実世界における何らかの活動を自動化するためのもの**であり、
オブジェクト指向の本質は、**「現実世界の登場人物とその振る舞いを、コンピュータ内の仮想世界で再現すること」**である。
　オブジェクト指向プログラミングでは、現実世界に出てくる登場人物(オブジェクト)の単位で、プログラムをクラスに分割する、そうして部品化したそれぞれの部品に登場人物の「責務」をプログラムとして書き込む。
　◆オブジェクトの責務
　　・情報保持責任
　　・行動責任
　オブジェクトはそれぞれの責務を果たすため、
　　・【属性】その登場人物に関する情報を覚えておく箱
　　・【操作】その登場人物が行う行動や動作の手順
　を持っている。

　◆オブジェクト指向の３大機能(詳しくは後で学習する)
　　・【カプセル化】属性や操作を、一部の相手からは利用禁止にする機能
　　・【継承】過去に作った部品を流用し、新しい部品を簡単に作れる機能
　　・【多様性】似ている２つの部品を「同じようなもの」とみなし、「いいかげん」に利用できる機能


#第8章　インスタンスとクラス
----------------------------------------------
####インスタンス
　　インスタンスは、仮想世界で活動するオブジェクトであり、
　　インスタンスを生み出すための金型的なものがクラスである。

　　Javaプログラムの組成に必要なクラス
　　・mainメソッドを含む一つの「神様のクラス」
　　・現実世界の登場人物を模した複数の「登場人物のクラス」

####属性の宣言方法【フィールド】
　　クラス内に宣言された変数をフィールドという。

```java:Heroクラスの名前とHPを変数として宣言
public class Hero {
        String name;  //nameフィールドの宣言
        int hp;       //hpフィールドの宣言
}
```

####定数フィールド
　　次のようにフィールド宣言と同時に初期値の設定も可能。
　　フィールド宣言の先頭にfinalをつけると、値の書き換えが不可能な**定数フィールド**となる。
　　(定数フィールドの名前は大文字で記述する)

```java:フィールドの宣言と同時に初期値の設定、定数フィールド
public class Hero {
        String name;           //nameフィールドの宣言
        int hp = 100;          //hpフィールドの宣言＆初期値の設定
        final int LEVEL = 10;  //LEVELフィールド(定数フィールド)の宣言
}
```

####操作の宣言方法【メソッド】
　　thisは「自分自身のインスタンス」を意味している。
　　.(ドット)は「の」という意味。

```java:Hero.java
public class Hero {
    String name;
    int hp;

    void sleep() {      //【操作の名前：眠る】
        this.hp = 100;  //this.hpは自分自身のhpフィールドのこと【処理結果】
        System.out.println(this.name + "は、眠って回復した！"); //this.nameは自分自身のnameフィールドのこと【処理結果】
    }
}
```


####クラス型変数
　　上記のように、Heroクラスを定義することで、「Heroクラスから仮想世界に生み出されたインスタンスを入れることができるHero型」が使用可能になる。
　　クラス型変数を使用することによって、仮想世界に複数存在しうる同名インスタンスの中から特定のインスタンスを識別する事ができる。

####インスタンスの生成方法＆フィールドへの値の代入

```java:インスタンスの生成、フィールドへの値の代入
public class Main {
   public static void main(String[] args) {
        Hero h = new Hero(); //勇者インスタンスを生成
        h.name = "ミナト";    //変数hのnameに代入
   }
}
```

####８章のRPGプログラム

```java:Main.java
public class Main {
    public static void main(String[] args) {
        Hero h = new Hero(); //勇者インスタンスを生成
        h.name = "ミナト";    //変数hのnameに代入
        h.hp = 100;          //変数hのhpに代入
        System.out.println("勇者" + h.name + "を生み出しました！");

        h.sit(5);   //５秒座れ
        h.slip();   //転べ
        h.sit(25);  //25秒座れ
        h.run();   //逃げろ
    }
}
```

```java:Hero.java
public class Hero {
    String name;
    int hp;

    void sleep() {      //【操作の名前：眠る】
        this.hp = 100;  //this.hpは自分自身のhpフィールドのこと【処理結果】
        System.out.println(this.name + "は、眠って回復した！"); //this.nameは自分自身のnameフィールドのこと【処理結果】
    }

    void sit(int sec) {  //【操作の名前：座る】
        this.hp += sec;
        System.out.println(this.name + "は、" + sec + "秒座った！");
        System.out.println("HPが" + sec + "ポイント回復した。");
    }

    void slip() {  //【操作の名前：転ぶ】
        this.hp -= 5;
        System.out.println(this.name + "は、転んだ！");
        System.out.println("5のダメージ");
    }

    void run() {  //【操作の名前：走る】
        System.out.println(this.name + "は、逃げ出した！");
        System.out.println("GAMEOVER");
        System.out.println("最終HPは" + this.hp + "でした");
    }

}
```

####８章の練習問題

```java:Main.java
  public class Main {
    public static void main (String[] args) {
        Cleric c = new Cleric();
        c.name = "主人公";

        System.out.println(c.name + "が誕生した！");
        System.out.println("ＨＰ：" + c.hp);
        System.out.println("ＭＰ：" + c.mp);

        c.selfAid();
        c.pray(6);

    }
  }
```

```java:Cleric.java
  public class Cleric {
    //【属性】
    String name;
    int hp = 50;
    final int MAX_HP = 50;
    int mp = 10;
    final int MAX_MP = 10;
    //【操作】
    //セルフエイド
    public void selfAid() {
        System.out.println(this.name + "はセルフエイドを唱えた！");
        this.hp = this.MAX_HP;
        System.out.println("ＨＰを全回復した。　 HP:" + this.hp);
        this.mp -= 5;
        System.out.println("ＭＰを5消費した。　　MP:" + this.mp);
    }
    //祈り
    public int pray(int second) {
        System.out.println(this.name + "は" + second + "秒間祈りを捧げた！");
        //ＭＰ回復分の計算(０〜２のランダム数＋祈りの秒数)
        int reflesh = new java.util.Random().nextInt(3) + second;
        //ＭＰ回復処理
        int after = this.mp + reflesh;
        //最大ＭＰを超えないようにする処理
        if (after > this.MAX_MP) {
            after = this.MAX_MP;
        }
        //回復した値を格納する変数の定義
        int difference = after - this.mp;
        System.out.println("ＭＰを" + difference + "回復した。　　MP:" + after);
        return reflesh;
    }
  }
```
+++++++++++++++++++++++++++実行結果++
主人公が誕生した！
ＨＰ：50
ＭＰ：10
主人公はセルフエイドを唱えた！
ＨＰを全回復した。　 HP:50
ＭＰを5消費した。　　MP:5
主人公は6秒間祈りを捧げた！
ＭＰを5回復した。　　MP:10
++++++++++++++++++++++++++++++++++++


#第9章　さまざまなクラス機構
----------------------------------------------
####ヒープ(heap)
　　Javaのプログラム実行時にJVMが準備するメモリ領域(通常数MB〜数GB)
　　イメージ的には、Javaのプログラムにより作り出される仮想世界で、
　　インスタンスが生成されるたびにその情報を格納するためにヒープの一部の領域が確保(通常数十〜数百バイト)される。つまり、インスタンスとは、ヒープの中の1部のメモリ領域のことである。

####参照の解決
　　「クラス型」も「配列型」と同じように、**「実際のデータが保存されているメモリ領域の先頭番地」**が変数に入っている。
　　変数から番地地黄法を取り出し、実際にその番地にアクセスする。という処理を**参照の解決**または**アドレス解決**という。

####インスタンスの独立性
　　同じクラスから生まれても、異なるインスタンスは互いに影響を受けない。

####クラス型をフィールドに用いる
####リスト９−３
```java:Sword.java
    public class Sword {
	String name;		// 剣の名前
	int damage;		// 剣の攻撃力
    }
```

```java:Hero.java
    public class Hero {
	String name;
	int hp;
	Sword sword;  //勇者が装備している剣の情報
	
	void attack(){
		System.out.println(this.name + "は攻撃した！");
		System.out.println("敵に5ポイントのダメージをあたえた！");
	}
	
	void sleep() {		/* 眠る(sleepメソッド) */
		this.hp = 100;
		System.out.println(this.name + "は、眠って回復した！");
	}
			/* 何秒座るか引数で受け取る */
	void sit(int sec) {	/* 座る(sitメソッド) */
		this.hp += sec;		/* 座る秒数だけHPを増やす */
		System.out.println(this.name + "は、" + sec + "秒すわった！");
		System.out.println("HPが" + sec + "ポイント回復した.");
	}
	
	void slip() { 		/* 転ぶ(slipメソッド) */
		this.hp -= 5;
		System.out.println(this.name + "は転んだ！");
		System.out.println("5のダメージ！");
	}
	
	void run() {		/* 逃げる(runメソッド) */
		System.out.println(this.name + "は、逃げ出した！");
		System.out.println("GAMEOVER");
		System.out.println("最終HPは" + this.hp + "でした");
	}
    }
```
####リスト９−４
```java:Main.java
    public class Main {
	public static void main(String[] args) {
		Sword s = new Sword();
		s.name = "炎の剣";
		s.damage = 10;

		Hero h = new Hero();
		h.name = "ミナト";
		h.hp = 100;
		h.sword = s;	// swordフィールドに生成済みの剣インスタンス（の番地）を代入
		
		System.out.println("現在の武器は" + h.sword.name);
				// ↑ 勇者「の」剣「の」名前
	}
    }
```
　　上記のHero.java４行目のように、「あるクラスが別のクラスをフィールドとして利用している関係」を**has-aの関係**という。
　　Hero **has-a** Swordとなる。（勇者は剣を持っている）
　　変数hには、勇者インスタンスのアドレス情報が入っている。勇者インスタンスにはSword領域があり、剣インスタンスのアドレス情報が格納されている。

####クラス型をメソッド引数や戻り値に用いる
####リスト９−５
```java:Wizard.java
    public class Wizard {
	String name;
	int hp;
	
	void heal(Hero h) {		// 引数はHero型
		h.hp += 10;		// 勇者のHPに10を加える
		System.out.println(h.name + "のHPを10回復した!");
	}
    }
```
####リスト９−６
```java:Main.java
public class Main {
	public static void main(String[] args) {
		Hero h1 = new Hero();
		h1.name = "ミナト";
		h1.hp = 100;

		Hero h2 = new Hero();
		h2.name = "アサカ";
		h2.hp = 100;
		
		Wizard w = new Wizard();
		w.name = "スガワラ";	
		w.hp = 50;
		
		w.heal(h1);		// ミナトを回復させる（HP: 100 -> 110）
		w.heal(h2);		// アサカを回復させる（HP: 100 -> 110）
		w.heal(h2);		// アサカを回復させる（HP: 110 -> 120）
	}
}
```
####String型の真実
　　String型は、Hero型と同じ「クラス型」である。
　　java.langパッケージに属するStringクラスであるため、インポート不要で利用できる。

####コンストラクタ
####フィールド初期値を自動設定する
####リスト９−８
```java:Main.java
public class Hero {
	int hp;	
	String name;
	Sword sword;
	
	void attack(){
		System.out.println(this.name + "は攻撃した！");
		System.out.println("敵に5ポイントのダメージをあたえた！");
	}
	
	void sleep() {		/* 眠る(sleepメソッド) */
		this.hp = 100;
		System.out.println(this.name + "は、眠って回復した！");
	}
			/* 何秒座るか引数で受け取る */
	void sit(int sec) {	/* 座る(sitメソッド) */
		this.hp += sec;		/* 座る秒数だけHPを増やす */
		System.out.println(this.name + "は、" + sec + "秒すわった！");
		System.out.println("HPが" + sec + "ポイント回復した.");
	}
	
	void slip() { 		/* 転ぶ(slipメソッド) */
		this.hp -= 5;
		System.out.println(this.name + "は転んだ！");
		System.out.println("5のダメージ！");
	}
	
	void run() {		/* 逃げる(runメソッド) */
		System.out.println(this.name + "は、逃げ出した！");
		System.out.println("GAMEOVER");
		System.out.println("最終HPは" + this.hp + "でした");
	}
	
	// 「このクラスがnewされた直後に自動的に実行される処理」を書いたメソッド
	Hero(){
		this.hp = 100;	// 自分自身のhpフィールドを100で初期化
	}
}
```
上記プログラムには、Hero()メソッドがあり、Heroクラスがnewされた直後に自動的に実行される。
このようなメソッドを**コンストラクタ**という。
※コンストラクタはh.Hero();のように直接呼び出すことはできない。

####コンストラクタとみなされる条件
①メソッド名がクラス名と完全に等しい
②メソッド宣言に戻り値が宣言されていない(void)も不可

####コンストラクタに情報を渡す
####リスト９−１０
```java:Main.Hero　コンストラクタで引数を追加情報として受け取る
    public class Hero {
	int hp;	
	String name;
	Sword sword;
	
	void attack(){
		System.out.println(this.name + "は攻撃した！");
		System.out.println("敵に5ポイントのダメージをあたえた！");
	}
	
	void sleep() {		/* 眠る(sleepメソッド) */
		this.hp = 100;
		System.out.println(this.name + "は、眠って回復した！");
	}
			/* 何秒座るか引数で受け取る */
	void sit(int sec) {	/* 座る(sitメソッド) */
		this.hp += sec;		/* 座る秒数だけHPを増やす */
		System.out.println(this.name + "は、" + sec + "秒すわった！");
		System.out.println("HPが" + sec + "ポイント回復した.");
	}
	
	void slip() { 		/* 転ぶ(slipメソッド) */
		this.hp -= 5;
		System.out.println(this.name + "は転んだ！");
		System.out.println("5のダメージ！");
	}
	
	void run() {		/* 逃げる(runメソッド) */
		System.out.println(this.name + "は、逃げ出した！");
		System.out.println("GAMEOVER");
		System.out.println("最終HPは" + this.hp + "でした");
	}
	
	Hero(String name){		// 引数として文字列を1つ受け取る
		this.hp = 100;	
		this.name = name;	// 引数の値でnameフィールドを初期化
	}
    }
```
####リスト９−１１
```java:Main.java　newする際に引数を渡す
    public class Main {
	public static void main(String[] args) {
		Hero h = new Hero("ミナト");	// こう書いておけばコンストラクタには「ミナトが渡される
		System.out.println(h.hp);		// 100と表示される
		System.out.println(h.name);	// ミナトと表示される
	}
    }
```
####リスト９−１２
```java:Main.java　コンストラクタのオーバーロード
    public class Hero {
	int hp;	
	String name;
	Sword sword;
	
	void attack(){
		System.out.println(this.name + "は攻撃した！");
		System.out.println("敵に5ポイントのダメージをあたえた！");
	}
	
	void sleep() {		/* 眠る(sleepメソッド) */
		this.hp = 100;
		System.out.println(this.name + "は、眠って回復した！");
	}
			/* 何秒座るか引数で受け取る */
	void sit(int sec) {	/* 座る(sitメソッド) */
		this.hp += sec;		/* 座る秒数だけHPを増やす */
		System.out.println(this.name + "は、" + sec + "秒すわった！");
		System.out.println("HPが" + sec + "ポイント回復した.");
	}
	
	void slip() { 		/* 転ぶ(slipメソッド) */
		this.hp -= 5;
		System.out.println(this.name + "は転んだ！");
		System.out.println("5のダメージ！");
	}
	
	void run() {		/* 逃げる(runメソッド) */
		System.out.println(this.name + "は、逃げ出した！");
		System.out.println("GAMEOVER");
		System.out.println("最終HPは" + this.hp + "でした");
	}
	
	Hero(String name){		// 以前からあったコンストラクタ1
		this.hp = 100;	
		this.name = name;	
	}

	Hero(){				// 新しく作ったコンストラクタ2
		this.hp = 100;	
		this.name = "名無しさん";	// ダミーの名前を設定する
	}

    }
```
　コンストラクタに引数を指定しなくてもエラーにならないように、引数がないコンストラクタも作成しておく。
####リスト９−１３
```java:Main.java　コンストラクタをオーバーロードしたクラスの利用
    public class Main {
	public static void main(String[] args) {
		Hero h1 = new Hero("ミナト");	// 文字列引数があるのでコンストラクタ1が呼び出される
		System.out.println(h1.name);	// 画面に「ミナト」と表示される

		Hero h2 = new Hero();		// 引数ないのでコンストラクタ2が呼び出される
		System.out.println(h2.name);	// 画面に「名無しさん」と表示される
	}
    }
```

本来、すべてのクラスは必ず何らかのコンストラクタを実行する事になっている。
コンストラクタを１つも定義していないクラスに限り、引数がなく、何も処理をしないコンストラクタ(デフォルトコンストラクタ)の定義がコンパイル時に自動的に追加される。。

####同一クラスの別コンストラクタの呼び出しに関するルール
　　「this.クラス名(引数);」と記述することはできない。
　　「this(引数);」と記述する。
####リスト９−１６
```java:コンストラクタの中から別のコンストラクタを呼び出す
	Hero(String name){		// 以前からあったコンストラクタ1
		this.hp = 100;	
		this.name = name;	
	}

	Hero(){				// 新しく作ったコンストラクタ2
		this("ダミー");		// コンストラクタ1を呼び出す	
	}
    }
```

####静的メンバ(static member)
####リスト9-18
```java:staticキーワードによるフィールドの共有
    public class Hero {
	int hp;	
	String name;
	static int money;		// 静的フィールド	
        ︙
    }
```
####静的フィールド
  　staticキーワードを指定したフィールドは**静的フィールド**という。
　　**静的フィールドの効果**
　　①フィールド変数の実態がクラスに準備される
　　　※インスタンスではなく、クラスに対して準備される変数のため、使用するには、
　　　　**クラス名.静的フィールド名**と記述する。
　　②全インスタンスに、静的フィールドの分身が準備される
　　　※**インスタンス変数名.静的フィールド名**と書いても、
　　　 **クラス名.静的フィールド名**と同じ意味になる。
　　③インスタンスを一つも生み出さなくても使用可能
　　　※静的フィールドは、クラスに所属するフィールドであるため、**クラス変数**ということもある。

####静的メソッド
　　staticキーワードがついているメソッドは、**静的メソッド**または**クラスメソッド**と呼ばれ、
　　静的フィールドとあわせて**静的メンバ**と総称される
　　**静的メソッドの効果**
　　①メソッド事態がクラスに属するようになる
　　　※インスタンスではなく、クラスに属するメソッドとなり、使用するには、
　　　　**クラス名.静的メソッド名();**と記述する。
　　②全インスタンスに、静的メソッドの分身が準備される
　　　※**インスタンス変数名.静的メソッド名();**と書いても、
　　　  **クラス名.静的メソッド名();**と同じ意味になる。
　　③インスタンスを一つも生み出さなくても使用可能

####静的メソッドの成約
　　静的メソッドの中に記述するコードでは、**staticがついていないフィールドやメソッドは利用できない。**
　　※静的メソッドは、一つもインスタンスがない状況でも呼び出される可能性があるメソッドであり、
　　 その状況ではインスタンスに所属するフィールドやメソッドを記述しても処理できないため。

####９章の練習問題

```java:Main.java
   public class Main {
    public static void main (String[] args) {
        Cleric c = new Cleric("john", 40, 8);
        
        System.out.println(c.name + "が誕生した！");
        System.out.println("ＨＰ：" + c.hp);
        System.out.println("ＭＰ：" + c.mp);

        c.selfAid();
        c.pray(6);
    }
   }

```

```java:Cleric.java
   public class Cleric {
    //【属性】
    String name;
    int hp;
    static final int MAX_HP = 50; //①静的フィールドの指定
    int mp;
    static final int MAX_MP = 10; //①静的フィールドの指定
    //【コンストラクタ】
    Cleric(String name, int hp, int mp){　//２ A)名前・HP・MPを指定してインスタンス化
        this.name = name;
        this.hp = hp;
        this.mp = mp;
    }
    Cleric(String name, int hp){          //２ B)名前・HPを指定してインスタンス化
        this(name, hp, Cleric.MAX_MP);　  //上の２ A)のコンストラクタの呼び出し＋ClericクラスのMAX_MP(静的フィールド)にアクセス
    }
    Cleric(String name){                  //２ C)名前・HPを指定してインスタンス化
        this(name, Cleric.MAX_HP);        //上の２ B)のコンストラクタの呼び出し＋ClericクラスのMAX_HP(静的フィールド)にアクセス
    }

    //【操作】
    //セルフエイド
    public void selfAid() {
        System.out.println(this.name + "はセルフエイドを唱えた！");
        this.hp = this.MAX_HP;
        System.out.println("ＨＰを全回復した。　 HP:" + this.hp);
        this.mp -= 5;
        System.out.println("ＭＰを5消費した。　　MP:" + this.mp);
    }
    //祈り
    public int pray(int second) {
        System.out.println(this.name + "は" + second + "秒間祈りを捧げた！");
        //ＭＰ回復分の計算(０〜２のランダム数＋祈りの秒数)
        int reflesh = new java.util.Random().nextInt(3) + second;
        //ＭＰ回復処理
        int after = this.mp + reflesh;
        //最大ＭＰを超えないようにする処理
        if (after > this.MAX_MP) {
            after = this.MAX_MP;
        }
        //回復した値を格納する変数の定義
        int difference = after - this.mp;
        System.out.println("ＭＰを" + difference + "回復した。　　MP:" + after);
        return reflesh;
    }
   }
```
+++++++++++++++++++++++++++実行結果++
  johnが誕生した！
  ＨＰ：40
  ＭＰ：8
  johnはセルフエイドを唱えた！
  ＨＰを全回復した。　 HP:50
  ＭＰを5消費した。　　MP:3
  johnは6秒間祈りを捧げた！
  ＭＰを6回復した。　　MP:9
++++++++++++++++++++++++++++++++++++

別コンストラクタの呼び出しを理解するのに苦労した。
今でも少し曖昧かもしれない。
【クラスパスの指定について参考にしたわかりやすい記事】
　Java Master > Java コンストラクタの使い方と概要
　http://kuwwta.hatenablog.com/entry/2016/05/12/141246

#第10章　カプセル化

####メンバ(フィールドおよびメソッド)に対する４つのアクセス制御レベル
　　　・private　アクセス修飾子：**private**
　　　　自分自身のクラスのみアクセス許可
       ※ただし、自分のクラスからthis.〜での読み書きは可能
　　　・package private　アクセス修飾子：**何も書かない**
　　　　自分と同じパッケージに属するクラスをアクセス許可
　　　・protected　アクセス修飾子：**protected**
　　　　自分と同じパッケージに属するか、自分を継承した子クラスをアクセス許可
　　　・public　アクセス修飾子：**public**
　　　　すべてのクラスをアクセス許可

　**フィールドのアクセス制御**
　　　アクセス修飾子 フィールド宣言;
　**メソッドのアクセス制御**
　　　アクセス修飾子 メソッド宣言{・・・}

　**【メンバに関するアクセス修飾の定石】**
　　　・フィールドはすべてprivate
　　　・メソッドはすべてpublic
　　　・クラスは特に理由がない限りpublic

####【getterとsetter】
　　　**getterメソッド**
　　　自分のクラスのフィールドを他クラスから呼び出せるようにするために、
　　　フィールドの中身を返すだけのメソッドを**getter**メソッドと言う。
　　　**getterメソッドの定石**
　　　public 値を取り出すフィールドの型 getフィールド名() {
       return this.フィールド名;
     }

　　　**setterメソッド**
　　　ある特定のフィールドに、指定された値を代入するだけの
　　　メソッドを**getter**メソッドと言う。
　　　**setterメソッドの定石**
　　　public void setフィールド名(フィールドの型 任意の変数名) {
       this.フィールド名 = 任意の変数名;
     }
　　　
####カプセル化のメリット
　　　1.ReadOnly、WriteOnlyのフィールドを用意できる。
　　　　外部から読めるが書き換えられないReadOnlyフィールドと、
　　　　外部から自由に書き換えできるが、読めないwriteOnlyフィールドを作成可能。

　　　2.クラスの内部設計を自由に変更できる。
　　　　他クラスからのフィールドの読み書きはgetter/setterを使用するため、
　　　　元々のフィールド名を自由に変更できる。

　　　３．フィールドへのアクセスを検査できる。
　　　　元々のフィールド情報の書き換えはsetterを通さないとできないため、
　　　　setterで設定されている値が妥当かの検査ができる。

####クラスに対する４つのアクセス制御レベル
　　　・package private　アクセス修飾子：**何も書かない**
　　　　自分と同じパッケージに属するクラスのみ許可
     ・public　アクセス修飾子：**public**
　　　　すべてのクラスを許可

####非publicクラス(package privateクラス)の特徴
　　　①クラス名がソースファイルと異なっても良い
　　　②１つのソースファイルに複数宣言しても良い

#第11章　継承

####継承を用いたクラスの定義
　　　class クラス名 **extends** 元となるクラス名 {
       親クラスとの差分メンバ
     }

　　　☆継承された親クラス（スーパークラス）と子クラス（サブクラス）の関係を**継承関係**という。
　　　※Javaでは、複数のクラスを親として1つの子クラスを定義すること(多重継承)はできない。

####オーバーライド
　　　親クラスのメンバを子クラス側で再定義（上書き）することを**オーバーライド（override）**という。

　　　つまり、子クラスに宣言されたメンバは、
　　　　①親クラスに同じメンバがなければ、そのメンバは「追加」になる。
　　　　②親クラスに同じメンバがあれば、そのメンバは「上書き変更」される。

####継承やオーバーライドの禁止
　　　◆クラス宣言にfinalをつけると、継承禁止
　　　◆メソッド宣言にfinalをつけると、オーバーライド禁止

####親インスタンス部へのアクセス
　　　◆親インスタンス部のフィールドを利用する
　　　　**super.フィールド名**
　　　◆親インスタンス部のメソッドを呼び出す
　　　　**super.メソッド名（引数）**

　　　　※祖父母クラス、親クラス、子クラスというふうな3重構造の継承関係のとき、
　　　　　子クラスから祖父母クラスへの直接のアクセスはできない。
　　　　　
####親クラスのコンストラクタの呼び出し
　　　Javaでは、**すべてのコンストラクタは、その先頭で必ず内部インスタンス部（＝親クラス）
　　　のコンストラクタを呼び出さなければならない**というルールがあるため、
　　　子クラスのコンストラクタを定義する際、最初の行に次のような記述をする必要がある。
　　　つまり、コンストラクタは、内側のインスタンス部分のものから順に呼び出される。

　　　**super（引数）;**
　　　
　　　※コンストラクタの最初の行にしか記述できない
　　　※記述していない場合、コンパイラによって自動的に挿入される
　　　 このため、**親クラスのコンストラクタに引数が指定されている場合は、
　　　 小クラスのsuper()に引数を入力しないとエラーになる**

####正しい継承、間違った継承
　####is-aの原則
　　　　子クラス**is-a**親クラス（小クラスは、親クラスの一種である）
　　　　例えば、名前や値段のフィールドを持つItemクラスを継承して住所や間取り、家の名前や家の値段フィールド
　　　　を持つHouseクラスを作ることは原理上可能だが、is-aの原則に当てはめると、「家はアイテムの一種です」
　　　　というのは不自然だ。
　　　　　◆将来、クラスを拡張していった場合に現実世界との矛盾が生じる（オブジェクト指向の原則から外れる）
　　　　　◆オブジェクト指向の3大機能の1つである「多様性」を利用できなくなる
　　　　上記の理由から、is-aの原則が成立しない場合は、継承を使ってはならない。

#第12章　高度な継承
####抽象クラス
　　　　未来の開発者のために、継承の材料となるクラスを作成するとき、下記の危険性がある。
　　　　①未来の開発者が詳細未定メソッドのオーバーライドを忘れる危険
　　　　②何もしないメソッドとの区別がつかない
　　　　③詳細未定メソッド(抽象メソッド)が含まれているのに、newされてしまう危険
　　　　そのために、Javaには詳細未定メソッドを記述する構文がある。

####詳細未定メソッド(抽象メソッド)の宣言
　　　　アクセス修飾子 **abstract** 戻り値 メソッド名(引数リスト);
　　　　
####抽象メソッドを含むクラス(抽象クラス)の宣言
　　　　アクセス修飾子 **abstract** class クラス名｛｝
　　　　抽象メソッドを１つでも含むクラスは、このようにabstractをつけた構文で宣言しなければならない。

　　　　そして、**抽象クラスはnewによるインスタンスが禁止される**

　　　　このような仕組みがあるため、上記の①〜③の危険性はない。
　　　　　①abstractがついた抽象クラスを継承した場合、親クラスの抽象メソッドも継承されているため、
　　　　　　子クラスも抽象クラスとして宣言するか、その抽象メソッドをオーバーライドしなければエラーとなる
　　　　　　そのため、未来の開発者が抽象メソッドのオーバーライドを忘れる危険はない。
　　　　　②abstractによって、詳細未定な抽象メソッドと判断できる
　　　　　③抽象クラスはnewによるインスタンスができない

####インターフェース
　　　下記の条件を満たすクラスをインターフェースとして定義することができる。
　　　①すべてのメソッドが抽象メソッド
　　　②基本的にフィールドを１つも持たない
　　　　※ただし、public static finalがついた定数フィールドだけは宣言が許される
　　　　 その場合、public static finalを省略できる。

####インターフェースの宣言
　　　アクセス修飾子 **interface** インターフェース名{}
　　　
　　　そして、インターフェースに宣言されたメソッドは、自動的にpublic abstractとなるので、
　　　**public abstractを省略できる。**

####インターフェースの実装
　　　アクセス修飾子 class クラス名 **implements** インターフェース名{}

####インターフェースの効果
　　　①同じインターフェースをimplementsする複数の子クラスに、
　　　　共通のメソッド群を実装するように強制できる
　　　②あるクラスがインターフェースを実装していれば、
　　　　少なくともそのインターフェースが定めたメソッドは持っていることが保証される

####インターフェースによる多重継承
　　　異なる実装が衝突する問題が発生しないため、複数の親インターフェースによる多重継承は認められている
　　　アクセス修飾子 class クラス名 i**mplements 親インターフェース名1,親インターフェース名2,** {}

####インターフェースの継承
　　　既存のインターフェースを拡張子して新しいインターフェースを定義することもできる。
　　　**public interface インターフェース名 extends 既存インターフェース名 {}**
    
##extendsとimplementsの両方を使ったクラス定義
　　**アクセス修飾子 class クラス名 extends 親クラス implements 親インターフェース1, 親インターフェース2,｛｝**


```java:リスト１２−１７

   public class Fool extends Character implements Human {
	// CharacterからhpやgetName()等のメンバを継承している
	// Characterから継承した抽象メソッド attack()を実装
	public void attack(Matango m){
		System.out.println(this.getName()  + "は、戦わずに遊んでいる。");
	}
	// さらにHumanから継承した4つの抽象メソッドを実装
	public void talk() {/* ... */}
	public void watch() {/* ... */}
	public void hear() {/* ... */}
	public void run() {/* ... */}
   }

```

####インターフェースメソッドのデフォルト実装
　　　default 戻り値 メソッド名(引数){
　　　　処理のデフォルト実装
　　　} 
　　　このようにして定義された抽象メソッドは、継承先でオーバーライドされなかった場合、
　　　デフォルト実装として定めた処理内容でオーバーライドされたものとみなされる。
　　　つまりnewでインスタンス化できる。

#第13章　多様性
####抽象クラスやインターフェースの型
　　　　抽象クラスやインターフェースからインスタンスを生み出すことはできないが、
　　　　型を利用することはできる。
　　　　→小クラスのインスタンスは親クラスの型に代入可能
　　　　　**親クラスの型　A　=　new　子クラス()；**

　　　　親クラスの型に代入した小クラスのインスタンスは、
　　　　親クラスが持っているメソッドしか利用できない。
　　　　
　　　　「箱の型」は、どのメソッドを「呼べるか」を決定する。
　　　　「中身の型」は、メソッドが呼ばれたら、「どう動くか」を決定する。

　　　　子クラスのメソッドを呼び出すために、親クラスの型に入っているインスタンスを
　　　　子クラスのものとして再認識させるには、キャストを使う。
　　　　今回のように、「親クラスに入っている子クラスのインスタンスを、子クラスの型に代入する」場合、
　　　　**ダウンキャスト**という。
　　　　**子クラス　任意インスタンス名　=　(子クラスの型)　親クラスに入っている子クラスのインスタンス;**

####キャストの失敗
　　　　親クラスに入っている子クラスのインスタンスを、ダウンキャストを使って
　　　　別の子クラスの型に代入しようとした場合、コンパイルは成功するが、動作させると、
　　　　**ClassCastException**というエラーが発生する。

####インスタンスを代入可能かチェックする
　　　　ClassCastExceptionを回避するために、安全にキャストできるかを判定するために
　　　　instanceof演算子というものがある。
　　　　**変数　instanceof　型名**
　　　　例)
　　　　　　if　(子クラスのインスタンス　instanceof　子クラスの型)｛
　　　　　　　　子クラスの型　任意インスタンス名　=　(子クラスの型)　子クラスのインスタンス；
　　　　　　｝

####同一視して配列を利用する
```java:練習１３−２　A.java
   public final class A extends Y {
	public void a( ) { System.out.print("Aa"); }
	public void b( ) { System.out.print("Ab"); }
	public void c( ) { System.out.print("Ac"); }
   }
```
```java:練習１３−２　B.java
   public class B  extends Y {
	public void a( ) { System.out.print("Ba"); }
	public void b( ) { System.out.print("Bb"); }
	public void c( ) { System.out.print("Bc"); }
   }
```
```java:練習１３−２　X.java
   public interface X {
	void a( );
   }
```
```java:練習１３−２　Y.java
   public abstract class Y implements X{
	public abstract void a( );
	public abstract void b( );
   }
```
```java:練習１３−２　Main.java
   public class Main {
	public static void main(String[] args) {
		Y[] array = new Y[2]; //Y(親要素)を配列変数として、まとめて扱うための配列
		array[0] = new A();   //ＡクラスをＹとして、まとめて扱う
		array[1] = new B();   //ＢクラスをＹとして、まとめて扱う
		for(Y y : array){     //配列を回す
			y.b();        //それぞれのインスタンスのbが実行される
		}
	}
}
```

#第14章　Javaを支える標準クラス
####日付を扱う
　　　Javaでは、日付情報を表すために使う型が１つではない。

　　　**形式１：long型の数値**
　　　　基本日時である1970年1月1日0分0秒(エポック)から経過したミリ秒(1/1000秒)で日時情報を表現する方法。
　　　　例えば、１３１６６２２２２５9３５というlong値は、「2011年9月22日1時23分45秒」を意味する。
　　　　System.currentTimeMillis()メソッドを呼べば、現在日時をlong型で得られるため、
　　　　次のような「処理時間の計測」を簡単に行える。

```java:リスト１４−１
   public class Main {
	   public static void main(String[] args){
		   long start = System.currentTimeMillis();

	   	   /* ここでなんらかの時間がかかる処理 */

	   	   long end = System.currentTimeMillis();

		   System.out.println("処理にかかった時間は..." +
			   (end-start) + "ミリ秒でした");
	    }
   }
```


　　　**形式2：Date型のインスタンス**　java.util.Dateクラス
　　　　Javaで日時情報を扱い場合に最も利用される形式。

　　　**現在日時を持つDateインスタンスの生成**
　　　　Date d = new Date(); 
　　　**指定時点の日時を持つDateインスタンスの生成**
　　　　Date d = new Date(long 値);

```java:リスト１４−１
     import java.util.Date;
       public class Main{
   	   public static void main(String[] args){
		Date now = new Date();
		System.out.println(now);
		System.out.println(now.getTime());
		Date past = new Date(1316622225935L);
		System.out.println(past);
	   }
      }

```

　　　**形式3:人間が読みやすいString型のインスタンス**
　　　　人間にとって読みやすいのは「2011年9月22日1時23分45秒」のような文字列だが、
　　　　場合によって、「2011/9/22 1:23:45」等、違う表示形式を取りたい場合もある。

　　　**形式4:人間が指定しやすい「6つのint」形式**
　　　　ある特定の日時情報を人間が入力する場合には、「年・月・日・時・分・秒」をそれぞれ整数(int値)として指定することが一般的。

　　　**Calendarクラスの利用** java.util.Calendarクラス
　　　　Date型と、6つのｉｎｔ値の相互変換
　　　　◆**6つのint値からDateインスタンスを生成する方法**
　　　　　Calendar c = Calendar.getInstance();
　　　　　c.set(年,月,日,時,分,秒);
　　またはc.set(calendar.YEAR,MONTH,DAY_OF_MONTH,HOUR,MINUTE,DAY);
　　　　　Date d = c.getTime();

　　　　◆**Dateインスタンスから6つのint値を生成する方法**
　　　　　Calendar c = Calendar.getInstance();
　　　　　c.setTime(d); //dはDate型変数
　　　　　int year = c.get(Calendar.YEAR);
　　　　　int month = c.get(Calendar.MONTH);
　　　　　int day = c.get(Calendar.DAY);
　　　　　int hour = c.get(Calendar.HOUR);
　　　　　int minute = c.get(Calendar.MINUTE);
　　　　　int second = c.get(Calendar.SECOND);

```java:リスト１４−３
   import java.util.Calendar;
   import java.util.Date;
   public class Main {
	    public static void main(String[] args) {
		// 現在の年を表示する
		   Date now = new Date();

		   Calendar c = Calendar.getInstance();
		   c.setTime(now);
		   int y = c.get(Calendar.YEAR);
		   System.out.println("今年は" + y + "年です");

		// 指定した日のDate型の値を得る
	 	   c.set(2010, 8, 22, 1, 23, 45);
		   c.set(Calendar.YEAR, 2011);
		   Date past = c.getTime();
   	    }
   }
```
　　　※Calendarを用いて「月」の情報を取得・設定する場合、
　　　　1〜12ではなく、**0〜11で指定する**。
　　　　2月を設定したい場合「c.set(Calendar.MONTH,1）」とする。

　　　**SimpleDateFormatクラスの利用** java.util.SimpleDateFormatクラス
　　　　◆**DateからStringを生成する方法**
　　　　　　SimpleDateFormat f = new SimpleDateFormat(※"yyyy/MM/dd");
　　　　　　String s = f.format(d); //dはDate型変数
　　　　◆**StringからDateを生成する方法**
　　　　　　SimpleDateFormat f =new SimpleDateFormat(※"yyyy年MM月dd日");
　　　　　　Date d = f.parse(文字列);

　　　※"yyyy/MM/dd"は書式文字列という。

```java:リスト１４−４
   import java.text.SimpleDateFormat;
   import java.util.Date;

   public class Main {
	   public static void main(String[] args) throws Exception {
		// 本日の日時を表示する
		   Date now = new Date();

		   SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		   String s = f.format(now);
		   System.out.println(s);

		// 指定日時の文字列を解析しDate型として得る
		   Date d = f.parse("2011/09/22 01:23:45");
   	   }
   }
```

　　　**書式文字列として利用可能な文字**

<table border="0" cellspacing="0" cellpadding="0">
        <tr>
          <th>文字</th><th>意味</th>
        </tr>
　　　　　<tr>
          <td>y</td><td>年</td>
        </tr>
        <tr>
          <td>M</td><td>月</td>
        </tr>
　　　　　<tr>
          <td>d</td><td>日</td>
        </tr>
        <tr>
          <td>E</td><td>曜日</td>
        </tr>
　　　　　<tr>
          <td>a/p</td><td>午前/午後</td>
        </tr>
        <tr>
          <td>H</td><td>時(0〜23)</td>
        </tr>
        <tr>
          <td>K</td><td>時(0〜11)</td>
        </tr>
        <tr>
          <td>m</td><td>分</td>
        </tr>
        <tr>
          <td>s</td><td>秒</td>
        </tr>
      </table>

```java:練習１４−１　Main.java
   import java.text.SimpleDateFormat;
   import java.util.Calendar;
   import java.util.Date;

   public class Main { 
     public static void main(String[] args){
       Date now = new Date();   //①現在の日付をDate型で取得
    
       Calendar c = Calendar.getInstance();
       c.setTime(now);   //②取得した日時をCalendarにセット

       int day = c.get(Calendar.DAY_OF_MONTH);  //③Calendarから「日」を取得
       day += 100;  //④取得した「日」に１００をプラス
    
       c.set(Calendar.DAY_OF_MONTH, day);  //④取得した「日」に１００をプラスした値をCalendarの「日」にセット
       Date date = c.getTime();   //⑤Calendarの日付情報をDate型に変換

       SimpleDateFormat result = new SimpleDateFormat("西暦yyyy年MM月dd日");
       String anser = result.format(date);    ⑥//SimpleDateFormatを用いて、Dateインスタンスの内容をanserに代入
    
       System.out.println(anser);   //結果を表示
     }
   }
```







#第15章　例外

####【３種類の不具合と対処方法】

　【Syntax Error】文法エラー
　　セミコロン忘れや、変数名の間違い、privateメソッドを外部から呼び出すなど、
　　文法の誤りによりコンパイルが失敗するエラー。
　　コンパイル時にエラーが発生するためコンパイル時に気づく。
　　コンパイラが指摘したコードの箇所を修正して解決する。

```terminal:文法エラーの例
   >javac SyntaxError.java
   SyntaxError.java4:';'がありません。

     }
     ^

　　エラー１個
```

　【Runtime Error】実行時エラー
　　配列の範囲外要素へのアクセス、０での割り算、存在しないファイルのオープンなど、
　　文法の問題がなく、コンパイルも実行もできるが、実行中に何らかの異常事態が発生し、
　　エラーメッセージが表示されて強制終了するエラー。
　　実行すると途中で終了するため、そこで気づく
　　予め「エラーが発生したときの対応策」を記述しておく。

```terminal:実行時エラーの例
   >javac RuntimeError.java
   >java RuntimeError
   プログラムを開始します。処理を３つ実行します。
   処理１を完了。
   処理２を完了。

   Exception in thread "main" java.lang.ArrayIndexOutOfBoundsExcepsion: 17
   at RuntimeError.main(RuntimeError.java:11)
```

　【LogicalError】論理エラー
　　Javaの文法に問題はなく、強制終了もしないが、プログラムの実行結果が想定と違う場合のエラー。
　　実行後に、想定外の処理結果となり気づく。
　　原因箇所を自力で探し、コードを修正して解決する。

```terminal:論理エラーの例
   >javac LogicalError.java
   >java LogicalError
   プログラムを開始します。
   ３+５を計算します。
   計算完了：　答えは３５
   プログラムを正常終了します。
```

####【例外的状況】
　
　実行時エラーの際「プログラム実行中に発生した想定外の事態」
　を**例外的状況**（exceptionalsituation）または**例外**（exception）という。　　
　例
　　◆パソコンのメモリがたりなくなった
　　◆存在すべきファイルが見つからない
　　◆nullが入っている変数を利用しようとした
　例外的状況に備えて準備した対策を、その状態に陥った場合に実施することを
　**例外処理**(exception handing)という。

####例外処理
　　例外的状況発生(プログラム実行時にエラーが発生)時に行う処理。
　　

####try-catch文
　　例外が発生する可能性がある処理に使う。try-catchを使うと、例外が発生しない場合の処理、例外が発生したときの処理を分けることができる。
　　※**finally**を使って例外の有無に関わらず必ず実行される処理を記述することもできる

```java
　　try {
        //例外が発生する可能性のある処理
   } catch (例外クラス　変数名) {
        //例外が発生した場合の処理(例外が発生しなければ行われない処理)
   } finally {
        //例外の有無に関わらず、最後に必ず実行される処理
   }
```

例外の種類

①**Error**系例外
　java.lang.Errorの子孫。
　**回復の見込みがない致命的な状況**を表すクラス。
　例）OutOfMemoryError(メモリ不足)
　　 ClassFormatError(クラスファイルが壊れている)
　※通常はこれらのエラーをキャッチところで打つ手がなく、キャッチする必要はない。

②**Exception**系例外
　java.lang.Exceptionの子孫(RuntimeExceptionを除く)
　**その発生を十分に想定して対処を考える必要がある例外的状況**を表すクラス。
　例)IOException(ファイルなどが読み書きできない)
　　 ConnectException(ネットワークに接続できない)
　※**try-catch文でキャッチしないとコンパイルエラーとなる**

③**RuntimeException**系例外
　java.lang.Exceptionクラスの子孫。
　**必ずしも常に発生を想定すべきとまでは言えない例外的状況**を表すクラス。
　例)NullPointerException(変数がnullである）
　　 ArrayIndexOutOfBoundsException(配列の添字)
　※いちいち想定しているときりがないようなものが多い
　　**try-catch文でキャッチするかは任意**

####例外の伝播
　例）Mainメソッドがsub()メソッドを呼び出し、さらにsub()メソッドがsubsub()メソッドを呼び出す
　　プログラムがあり、そのsubsub()メソッド内で例外が発生した場合、
　　subsub()メソッドにtry-catch文がなければ呼び出し元のsub()メソッドに例外の対応が求められ、
　　sub()メソッドにもtry-catch文がなければ呼び出し元のMainメソッドに対応が求められ、
　　Mainメソッドにもtry-catch文がなければ強制終了する。
　　上記のような減少を例外の伝播という。

　　Exception系例外に関しては、try-catch文がないとコンパイルエラーとなるため、
　　基本的に例外の伝播は起こらないが、**スロー宣言(throws)**を行うことで、発生するチェック例外を
　　呼び出し元へと伝播させることができる。
####スロー宣言による例外伝播の許可
　　アクセス修飾　戻り値　メソッド名(引数リスト)
　　　　**throws**例外クラス1、例外クラス2///{
　　メソッドの処理内容
　　}
　　このようにスロー宣言を行うと、IOExceptionのような例外が発生する可能性がある場合でも
　　コンパイルエラーにはならない。
　　※**スロー宣言を行ったメソッドの呼び出し元のメソッドに、try-catchを記述する義務が生まれる**


####例外インスタンスを自分で投げる
　　　throw　new　例外クラス名("エラーメッセージ");
　　　下記のプログラムのように、例外をチェックするプログラムを作成することもできる。

```java:リスト15-5　例外インスタンスを自分で投げる
public class Person{
  int age;
  public void setAge(int age) {
    if(age < 0) {		// ここで引数をチェック
      throw  new IllegalArgumentException("年齢は正の数を指定すべきです。指定値=" + age);
    }
    this.age = age;    // 問題ないなら、フィールドに値をセット
  }
}
```
```java:
public class Main{
  public static void main(String[] args){
    Person p = new Person();
    p.setAge(-128);	 //誤った値のセットを試みる→例外発生
  }
}
```