【Java・学習ログ12】Objectクラス／静的メンバについて

教本に沿ってやってみたシリーズ、『第14章』。
≪使用教材≫スッキリわかるJava入門　第3版　スッキリわかるシリーズ

## ■java.lang.Objectの継承

javaでは親なしのクラスを定義できない。定義する際に指定がなければ、「java.lang.Object」が親クラスとして継承される。objectクラスには **equals()、toString()** のメソッドが定義されており、どのメソッドでも呼び出すことができる。

指定のないクラスは全てextends.Objectを持っているとされ、多態性の法則によってどんなインスタンスでもobject型に格納でできる。<font color=red>※基本データ型(int,longなど)以外</font>

```java
Object 01 = new Empty();
Object 02 = new Hero();
Object 03= "おはようございます。"
```

#### Objectクラスに定義されたメソッドを呼び出す
* <b>toString()メソッド</b>
オブジェクト(インスタンス)の中身を文字列で表示してくれるメソッド。
```java
class Hero { 
    String name;
    int hp;
}

public class Main {
    public static void main(String[] args) {
        Hero h = new Hero();
        h.name = "ヤマト";
        h.hp = 100;
        System.out.println(h.toString()); 
// Heroインスタンスで定義された情報を呼び出す
    }
}
```
【実行】
![スクリーンショット 2023-08-20 051054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/c70193fa-32f6-f972-631f-6568e49df141.png)
※Heroクラスで改めてtoString()を再定義していないため、上記の記述だとObjectクラスに定義されているシンプルな形式で表現されてしまう。
指定の形式で返すには、Heroクラスで<b>オーバーライド</b>でし、メソッドを再定義する必要がある。

【オーバーライド後】
![スクリーンショット 2023-08-20 051354.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/978892b0-c34d-8641-68f5-ae8ca5c96349.png)
![スクリーンショット 2023-08-20 051335.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/9957a328-5bea-590b-c47b-3aa2ebdfacd0.png)
【実行】
![スクリーンショット 2023-08-20 053515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/a6aa9011-fe2d-a2d4-783f-70d43e60994a.png)

* <b>eqials()</b>
２つのインスタンスが「同じ内容であるか」を判定する目的で使われる。

例1:等値(==)判定…インスタンスのアドレスを判定する
例2:等価(epuals)判定…インスタンスの中身を判定する

```java
// 例1:この場合、h1 == h2
Hero h1 = new Hero("ヤマト");
Hero h2 = h1;

// 例2:この場合、h1.equals(h2)
Hero h1 = new Hero("ヤマト");
Hero h2 = new Hero("ヤマト");
```
equalsで正しく等価判定させるには、オーバーライドして予め何を持って等価とするかを指定する必要がある。

【オーバーライド後】
```java
public class Hero {
    String name;
    int hp;

    public boolean equals(Object o) {
        if (this == o) { return true; }
        if (o instanceof Hero) { // instanceof演算子
            Hero h = (Hero)o; // Object型をHero型にキャスト
            if (this.name.equals(h.name)) { // this.name（この場合は　Object o）equals h.name
            return true; // true を返す
            }
        }
        return fales;
    }
}
```
## ■静的メンバ
staticで指定したフィールドやメソッドのこと。
同クラスから生成されたインスタンス間で1つのフィールドを共有できる。

* <b>静的フィールド</b>
インスタンスではなくクラスに属するフィールド。
```java
/* 定義　*/
public clas Hero{
    String name;
    int hp;
    static int mondy; // 静的フィールド
}
/*【アクセス】*/
// (１) クラス名.静的フィールド名
 public class Main {
        public static void main(String[] args){
            Hero h1 = new Hero();
            Hero h2 = new Hero();
            System.out.println(Hero.money); // ★
// (２) インスタンス変数名.静的フィールド名
public class Main {
    public static void main (String[] args) {
        Hero h1 = new Hero;
        Hero h2 = new Hero;
        Hero.maney = 100; 
        System.out.println(Hero.name);
        System.out.println(h1.money);
        h1.money = 300; // Hero.moneyに300を代入
        System.out.println(h2.money); 
        // 実行すると「300」が表示される。
        // クラスに属する１つのフィールドが共有されているため、イスタンス毎の代入は不可能。
    }
}
```
##### ※メインクラスでの呼び出し
静的フィールドは金型（クラス）の上に用意される箱。
よってメインクラスではインスタンスの作成不要で呼び出しできる。この特徴を**クラス変数**という。

* <b>静的メソッド(クラスメソッド)</b>
インスタンスではなくクラスに属するメソッド。
```java
/* 定義　*/
public class Hero {
	String name;
	int hp;
	static int money;
	// Heroの所持金をランダムな金額で設定
	public static void setRandomMoney() {
		Hero.money = (int)(Math.random() * 1000);
	}
}
/*【アクセス】*/
public class Main {
	public static void main(String[] args) {
		Hero.setRandomMoney();
		System.out.println(Hero.money); 
		Hero h1 = new Hero();
		System.out.println(h1.money);　// 上記と同数が表示される。
	}
}
```
前述のとおりnewをしなくても使用ができる静的メソッドだが、呼び出した静的メソッド内にstaticが付いていない（インスタンスの生成を必要とする）フィールドやメソッドがある場合、エラーが発生する。
- - -
(簡易メモ)
1. Objectクラスのメソッドを呼び出しする際は要再定義。オーバーライドを忘れないこと。
1. 手軽に呼び出したい場合には便利な静的メンバだが、制約もあるため使いどころに要注意である。