【16章】Javaを学ぼう

今回の記事は前章で作成した自己紹介プログラムをさらに改善していきたいと思います。
私自身のアウトプットの場となりますので、よろしくお願いいたします！

##前章で作成した自己紹介プログラム（前提）

```java:Person.java
//インスタンスフィールドを定義
class Person {
 public String firstName;
 public String lastName;
 public int age;
 public double height;
 public double weight;
 
//コンストラクタを定義し、インスタンスフィールドに値をセット
 Person(String firstName, String lastName, int age, double height, double weight) { 
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.height = height;
  this.weight = weight;
 }

 //fullNameメソッドを定義
 public String fullName() {
  return this.firstName + " " + this.lastName;
 }
 
 //bmiメソッドを定義
 public double bmi() {
  return this.weight / this.height / this.height;
 }

 // printDataメソッドを定義
 public void printData() {
  System.out.println("私の名前は" + this.fullName() + "です");
  System.out.println("年齢は" + this.age + "歳です");
  System.out.println("BMIは" + Math.round(this.bmi()) + "です");
 }
}
```

```java:Main.java
class Main {
 public static void main(String[] args) {
  Person person1 = new Person("John", "Connor", 28, 1.7, 65.0);

  person1.printData();
  //printDataメソッドを定義したため不要
  //System.out.println(person1.fullName()); 
  //System.out.println(person1.age);
  //System.out.println(person1.bmi());
 }
}
```

上記が前章で作成した自己紹介プログラムです。それではさらに改善を行っていきたいと思います！
##クラスフィールドとその定義
前章ではインスタンスに属するインスタンスフィールドを学習してきましたが、クラスに属する、クラスフィールドというものもあります。クラスフィールドは、staticをつけて**「public static データ型 変数名」**と定義します。

```java:Person.java
//クラスフィールドを定義
class Person {
 public static データ型 変数名;
       //クラスフィールドにはstaticをつける
}
```

##クラスフィールド具体例
何人分のインスタンスを生成したか数えるために、countというフィールドで、インスタンスの生成回数を保存するようにしてみます。
countは個々のインスタンスが持つものではなく、Personクラスが持っていればよいので、クラスフィールドにしてあげましょう。また、countはインスタンスの生成回数なので、下図のように定義時に0を代入しておきます。

```java:Person.java
class Person {
 public static int count = 0;
 //クラスフィールド
 public String firstName;
 public String lastName;
 //インスタンスフィールド
   .
   .
   .
}
```

##クラスフィールドへのアクセス
クラスフィールドには「クラス名.クラスフィールド名」でアクセスすることができます。

```java:Person.java
class Person {
 public static int count = 0;
   .
   .
   .
 Person(String firstName, String lastName,....)
  Person.count ++;
 }
}
```

上図ではコンストラクタで、countに1を足しています。このようにすれば、インスタンスの生成の度にcountに1が追加されていくので、下図で取得しているcountの値が変化していきます。

```java:Main.java
class Main {
 public static void main(String[] args) {
  System.out.println("合計" + Person.count + "人です");
  Person person1 = new Person(...);
  System.out.println("合計" + Person.count + "人です");
 }
}
```

出力結果↓

```java:コンソール
合計0人です
合計1人です
```

それでは、自己紹介プログラムにint型のクラスフィールドcountを追加してみます。

```java:Person.java
class Person {
 public static int count = 0; //int型のクラスフィールドcountを定義し、0を代入する
 public String firstName;
 public String lastName;
 public int age;
 public double height, weight;
 
 Person(String firstName, String lastName, int age, double height, double weight) { 
  this.count ++; //変数countに1を足す
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.height = height;
  this.weight = weight;
 }

 public String fullName() {
  return this.firstName + " " + this.lastName;
 }
 
 public double bmi() {
  return this.weight / this.height / this.height;
 }

 public void printData() {
  System.out.println("私の名前は" + this.fullName() + "です");
  System.out.println("年齢は" + this.age + "歳です");
  System.out.println("BMIは" + Math.round(this.bmi()) + "です");
 }
}
```

```java:Main.java
class Main {
 public static void main(String[] args) {
  Person person1 = new Person("John", "Connor", 28, 1.7, 65.0);
  person1.printData();
  Person person2 = new Person("Mia", "Olivia", 20, 1.5, 45.0);
  person2.printData();

  System.out.println("合計" + Person.count + "人です");
 }
}
```

出力結果↓

```java:コンソール
私の名前はJohn Connorです
年齢は28歳です
BMIは23です
私の名前はMia Oliviaです
年齢は20歳です
BMIは20です
合計は2人です
```

##クラスメソッド
クラスフィールドがクラスに属するフィールドであるように、クラスに属するメソッドもあります。これを**クラスメソッド**といいます。クラスメソッドの定義は、**「public static 戻り値の型 メソッド名()」**とします。

```java:Person.java
class Person {
 public static 戻り値の型 メソッド名() {  //クラスメソッドにはstaticをつける
  //処理
 }
}
```

クラスメソッドは**「クラス名.メソッド名()」**と呼び出します。これはクラスメソッドがクラスに属しているためです。クラスメソッドは**インスタンスを生成しない状態でも呼び出すことが可能**です。

```java:Person.java
class Person {
 public static int count = 0;
   .
   .
   .
 public static void printCount() {
  System.out.println("合計" + Person.count + "人です");
 }
}
```

```java:Main.java
class Main {
 public static void main(String[] args) {
  Person.printCount();
  Person person1 = new Person(...);
  Person.printCount();
 }
}
```

出力結果↓

```java:コンソール
合計0人です
合計1人です
```

それでは、クラスメソッドを定義し、自己紹介プログラムに追加していきます。

```java:Person.java
class Person {
 public static int count = 0;
 public String firstName;
 public String lastName;
 public int age;
 public double height, weight;
 
 Person(String firstName, String lastName, int age, double height, double weight) { 
  this.count ++; 
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.height = height;
  this.weight = weight;
 }

 public String fullName() {
  return this.firstName + " " + this.lastName;
 }
 
 public double bmi() {
  return this.weight / this.height / this.height;
 }

 // クラスメソッドprintCount()を定義
 public static void printCount() {
  System.out.println("合計" + Person.count + "人です");
 }

 public void printData() {
  System.out.println("私の名前は" + this.fullName() + "です");
  System.out.println("年齢は" + this.age + "歳です");
  System.out.println("BMIは" + Math.round(this.bmi()) + "です");
 }
}
```

```java:Main.java
class Main {
 public static void main(String[] args) {
  Person person1 = new Person("John", "Connor", 28, 1.7, 65.0);
  person1.printData();
  Person person2 = new Person("Mia", "Olivia", 20, 1.5, 45.0);
  person2.printData();

  Person.printCount();
 }
}
```

出力結果↓

```java:コンソール
私の名前はJohn Connorです
年齢は28歳です
BMIは23です
私の名前はMia Oliviaです
年齢は20歳です
BMIは20です
合計は2人です
```

今回はここまでにしたいと思います。次章ではコンストラクタのオーバーロードを中心に学び、今回作成した自己紹介プログラムをさらに改善していきたいと思います。
よろしくお願いいたします！
最後までご覧いただきまして、ありがとうございました！