Hello Worldからの復習 ～this,super編～

##### お品書き
+ this、superって？
+ thisキーワード
+ superキーワード
+ メリット
+ thisとsuperによるコンストラクタの呼び出し
+ this(～)Sample
+ super(～)Sample


----

this、superって？
-

**メンバー変数・メソッドの呼び出し**

:::note
this.～ = **このオブジェクトの～**
super.～ = **スーパークラスの～**
:::

◆thisキーワード
-


```java:例
class Person{
  String name;
  void setName(String name){
    this.name = name;
    }
    void display{
    ...
    }
}

class Student extends Person{
  int stuNo;
  void display(){
  super.display();
  System.out.println(stuNo);
  }
}

```

引数のnameとメンバー変数のnameの名前が被ってしまって区別がつかなくなってしまうが、**thisキーワード**を使って区別をつけることができる。
```java:this
this.name = name
/*
*setNameの引数のString nameを表す左辺のname
*オブジェクトのメンバー変数を表す右辺のthis.name
*/
```

これまではこんな感じで記述していたね。↓
```java:例2
String name;
void setName(String n){
  name = n;
  ```

  thisキーワードを使うことによって、引数の名前をメンバー変数の名前と合わせることが出来る。


◆superキーワード
-

```java:例3
class Student extends Person{
  int stuNo;
  void display(){
  super.display(); //superClassのdisplay()を呼び出す
  System.out.println(stuNo);
  }
}
```
例3ではdisplayメソッドをオーバーライドしているが、superClassのdisplayメソッドを呼び出しているため、オーバーライド前(上書き前)の処理を呼び出す記述
そのため、Studentクラスでnameの情報を記述する必要はなく、nameの表示はPersonクラスの表示を呼び出し、stuNoはStudentクラスで表示する。

ってことは

```java:java
Student stu = new Student();
stu.display(); //↓
```
とすると↓
```java:java
class Person{
  String name;
  void setName(String name){ //3
    this.name = name;
    }
    void display{
    ...
    }
}

class Student extends Person{
  int stuNo;
  void display(){ //1
  super.display(); //2
  System.out.println(stuNo);
  }
}

```
のような順番で処理される

メリット
-
superキーワードを使うと、同じコードを書かなくてよい
修正する場合、super.～のところの修正で済む。

thisキーワードのおかげで引数の名前をわざわざ考えなくてよい
引数の名前を考えるくらいと思うが、プログラムを自動で作成する際、重宝する。


◆thisとsuperによるコンストラクタの呼び出し
-

:::note
**this(引数)、super(引数)**
:::

キーワードの後に`( )`を書くと
**コンストラクタの呼び出す**ことができる

クラスの中にいくつかコンストラクタを書きたい
そして
コンストラクタのなかで似たような処理をさせたい
でも同じ処理を何回も書くのは嫌だから

thisとsuperを使ってそれぞれ呼び出して利用しようという話。

:::note
this(～)は同じクラスの中でコンストラクタを呼び出しあうことができる。

super(～)はスーパークラスのコンストラクタを呼び出す事ができる
:::


this(～)Sample
-
```java:java
class Person{
  String name;
  Person(){ //コンストラクタ
    this("未設定");
  }
  Person(String name){ //コンストラクタ
    this.name = name; //コンストラクタのString nameをthis.nameに代入
    }
}
```

文字列を代入するという処理が書かれているため、このPersonのコンストラクタを利用しよう↓
```java:this
Person(String name){
this name = name;
}
```
このthisはこのクラスを意味するので、thisはPersonに置き換わるイメージ
```java:java
Person(){
  this("未設定")
  }
  ↓
  Person(String name){
this name = name;
}
  ```
  文字列の("未設定")がthis.nameに代入される。

◆super(～)Sample
-

```java:java
class Student extends Person{
  int stuNo;
  .
  .
  Student(String name, int stuNo){ //コンストラクタ
    super(name); //名前の設定はSuperClassで定義しているから呼び出す
    this.stuNo = stuNo;
    }
}
```
このsuperでPersonクラスのメソッドを再び呼び出す
```java:this
Person(String name){
this name = name;
}
```

※**this(),super()はコンストラクタ内の**先頭**に記述
(なければ自動的に`super( );`が挿入される)

メモリ上にオブジェクトの領域を取るときに、スーパークラスから変数などを作っていく流れになっているため、
thisやsuperを記述するときは先頭にする。


```java:java
public class Person3{
  private String name;

  public Person3(String name){ //名前を受け取る
    this.name = name; /*
    *受け取った名前の代入　
    *thisはこのオブジェクトのという意味のため、  private String name;
を指している
*/
  }
  public void display(){
    System.out.println("名前：" + name);
  }
}
```

```java:java
public class Student3 extends Person3{
  private int stuNo;

  public Student3(String name){ //コンストラクタ
    this(name, 999); //コンストラクタの呼び出し　ここのthisはStudent3
  }
  public Student3(String name, int stuNo){ //コンストラクタ　thisで呼び出した情報が入る
    super(name); //スーパークラスのthis name = name;が実行される
    this.stuNo = stuNo; //メンバー変数に代入
  }
  public void display(){ //スーパークラスのdisplayをオーバーライド
    super.display(); //スーパークラスのdisplay()が呼び出される
    System.out.println("学籍番号：" + stuNo); //スーパークラスのdisplay()が呼び出された後に表示
  }
}
```

```java:java
public class StuSample3{
  public static void main(String[] args){
    Student3 stu = new Student3("大輔"); //オブジェクトの生成、コンストラクタに名前を渡している
    stu.display();
  }
}
```

```cmd:cmd
C:\Java\1>java StuSample3
名前：大輔
学籍番号：999
```


`this.`や`super.`はメンバー変数やメソッドの呼び出し
`this()`や`super()`は同じクラス、あるいはsuperクラスのコンストラクタの呼び出しということを区別して理解しよう。