【Java基礎】Classとは

## はじめに
当記事は、[やさしいJava](https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%84Java-%E7%AC%AC7%E7%89%88-%E3%80%8C%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E9%AB%98%E6%A9%8B-%E9%BA%BB%E5%A5%88/dp/4815600848)という参考書で独学した知識の整理の為に書きました。

## Classとは
モノ一般に関する状態・性質や機能をまとめたもの

- field：クラスの「状態・性質」を表す仕組み
- method：クラスの「機能」を表す仕組み
- member： field、method...etcのこと

## Classの宣言
クラスは次のように宣言します。

```html:
class クラス名
{
    型名 フィールド名;
    ・・・
    戻り値の型 メソッド名(引数リスト)
    {
　　　　文;
　　　　・・・
　　　　return 式;
    }
    ・・・
}
```

## Classの利用
クラスを宣言しただけでは、それがどういったモノなのか詳細には分かりません。
そこで必要となるのが、オブジェクトの作成です。

例として、「車」に置き換えて考えてみます。

```java:
// 車クラス
class Car
{
    // フィールド
    int num; // 車のナンバー
    double gas; // ガソリンの量
}
```

上記の段階で、「車」というモノは「ナンバー」と「ガソリンの量」を持つことが分かります。
あとは、宣言したクラスを基に、１台の車を作るみたくコードを記述していくだけです。

- このように、コード上で作成される車１台１台のことを、object/instanceといいます。

```java:
// 車クラスのオブジェクトを作成
class Sample1
{
    public static void main(String[] args)
    {
        Car car1 = new Car();

        car1.num = 1234;
        car1.gas = 20.5;

        System.out.println("車のナンバーは" + car1.num + "です。");
        System.out.println("ガソリン量は" + car1.gas + "です。");
    }
}
```

- オブジェクトを作成すると、メンバにアクセスすることができる

**クラスを利用するには、クラスを宣言して、オブジェクトを作成する。**

## Constructor
クラスの中には、フィールドとメソッドのほかに、コンストラクタというものを記述できます。

コンストラクタは、メソッドと非常に似ていますが、

- コンストラクタの名前は、必ずクラス名と同じ
- 戻り値を指定できない
- そのクラスのオブジェクトが作成されたときに、定義しておいたコンストラクタ内の処理が自動的に行われる

といった違いがあります。

```java:
class Car
{
	private int num;
	private double gas;

	// constructor
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}

	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
}

class Sample
{
	public static void main(String[] args)
	{
		Car car1 = new Car();
		car1.show();
	}
}
```

下記、実行結果

```html:
車を作成しました。
車のナンバーは0です。
ガソリン量は0.0です。
```

## Classの機能

### カプセル化
クラスの中にデータ（フィールド）と機能（メソッド）のをひとまとめにし、保護したいメンバにprivateをつけて勝手にアクセスできなくする機能。

例）フィールド→privateメンバ、メソッド→publicメンバ

これにより、誤りの起きにくいプログラムを作成できます。

- public：クラスの外からでもアクセスできる
- private：クラスの外から勝手にアクセスできない
- どちらもかかない（省略）：「同じパッケージ」に含まれるクラス内からアクセスできる

### オーバーロード
同じクラス内でも、同じメソッド名で異なる引数の型・個数をもつメソッドを定義できること。
※コンストラクタもオーバーロード可

```java:
class Car
{
	private int num;
	private double gas;

	public void setCar(int n)
	{
		num = n;
		System.out.println("ナンバーを" + num + "にしました。");
	}

	public void setCar(double g)
	{
		gas = g;
		System.out.println("ガソリン量を" + gas + "にしました。");
	}

	public void setCar(int n, double g)
	{
		num = n;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}

	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
}

class Sample
{
	public static void main(String[] args)
	{
		Car car1 = new Car();
		car1.setCar(1234, 20.5);
		car1.show();

		System.out.println("車のナンバーだけ変更します。");
		car1.setCar(2345);
		car1.show();

		System.out.println("ガソリン量だけ変更します。");
		car1.setCar(30.5);
		car1.show();
	}
}
```

出力結果は、下記になります。

```html:
ナンバーを1234にガソリン量を20.5にしました。
車のナンバーは1234です。
ガソリン量は20.5です。
車のナンバーだけ変更します。
ナンバーを2345にしました。
車のナンバーは2345です。
ガソリン量は20.5です。
ガソリン量だけ変更します。
ガソリン量を30.5にしました。
車のナンバーは2345です。
ガソリン量は30.5です。
```

上記コードでは、３種類のsetCar()メソッドを呼び出しています。

- 1番目に、引数が２個のもの
- 2番目に、引数がint型のもの
- 3番目に、引数がdouble型のもの

似たような処理について同じメソッド名を利用することができ、とても便利です。
<font color="Red">※ただし、引数の型または個数が異なってなければ、オーバーロードできないので注意！</font>

## 継承
Javaでは、既に作成したクラスを基に、新しいクラスを作成できる。

- 新しいクラスを作成することを、extends(クラスを拡張する)という。

車を例にすると、下記のようになり、

```html:
class 車
{
    ナンバー;
    ガソリン量;
    ナンバーとガソリン量を表示する機能
}

class レーシングカー extends 車
{
    競技用コース;
    競技用コースを表示する機能;
}
```

- 親元のクラス「車」をスーパークラス
- 追加したクラス「レーシングカー」をサブクラス

といい、サブクラスはスーパークラスのメンバを継承する。

<font color="Red">※注意：複数のスーパークラスのメンバを１つのサブクラスで継承はできない。</font>

### メンバへのアクセス
スーパークラスのprivateメンバには、サブクラスからもアクセスできません。

そのため、スーパークラスでは、protectedという指定することができます。

- protected：サブクラスのほか、同じパッケージに属するクラスからもアクセスできる。

### オーバーライド
スーパークラスと全く同じメソッド名・引数の数・型をもつメソッドを定義できる。

```java:
class Car
{
	protected int num;
	protected double gas;

	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}

	public Car(int n, double g)
	{
		num = n;
		gas = g;
		System.out.println("ナンバー" + num + "ガソリン量" + gas + "の車を作成しました。");
	}

	public void setCar(int n, double g)
	{
		num = n;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}

	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
}

class RacingCar extends Car
{
	private int course;

	public RacingCar_11()
	{
		course = 0;
		System.out.println("レーシングカーを作成しました。");
	}

	public void setCourse(int c)
	{
		course = c;
		System.out.println("コース番号を" + course + "にしました。");
	}

	public void show()
	{
		System.out.println("レーシングカーのナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
		System.out.println("コース番号は" + course + "です。");
	}
}

class Sample
{
	public static void main(String[] args)
	{
		RacingCar rccar1 = new RacingCar();
		rccar1.setCar(1234, 20.5);
		rccar1.setCourse(5);
		rccar1.newShow();
	}
}
```

下記、実行結果

```html:
車を作成しました。
レーシングカーを作成しました。
ナンバーを1234にガソリン量を20.5にしました。
コース番号を5にしました。
レーシングカーのナンバーは1234です。
ガソリン量は20.5です。
コース番号は5です。
```

サブクラスのオブジェクトを作成し、show()メソッドを呼び出すと、サブクラスのshow()メソッドが呼び出されました。

<font color="Red">※メソッド名・引数の数・型が全く同じの場合、サブクラスで新しく定義したメソッドが呼び出されるようです。</font>

### final
スーパークラスのメソッドの先頭にfinalをつけると、オーバーライドを回避することができます。

## 参考
- [やさしいJava](https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%84Java-%E7%AC%AC7%E7%89%88-%E3%80%8C%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E9%AB%98%E6%A9%8B-%E9%BA%BB%E5%A5%88/dp/4815600848)