javascriptの初心者がクラスについて勉強したことのメモ

こんにちは、[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているmaec_lamarです。
javascriptのクラスを勉強したことについて書きたいと思います。
javascriptについては、勉強を初めて１週間弱ですし、他の言語でクラスを扱った経験もありませんので、
クラスについて間違って理解しているかもしれません。
もし内容に誤りがありましたら、指摘をお願いします。


#クラスとは

クラスは、javascriptでは、ES6から追加された概念で、javaやpythonなどにも存在します。
クラスとは、データと処理をひとまとめにしたもののことで、設計書のような役割を果たしています。
C言語でいう構造体に近いかなと思います。
例えば、学校の学級のメンバーのデータを管理するときに使います。
クラスは、以下のようにして定義します。

```javascript:member.js
class member{} //クラスmemberの定義
```

そして、この設計書に基づいて生成される具体的なメンバーのことをインスタンスと呼び、以下のように、newを用いて定義します。

```javascript:member.js
class member{}

const member1 = new member(); //インスタンスmember1の生成
const member2 = new member();
```

#コンストラクタとメソッド

インスタンスを生成する際の処理を行う機能のことを、「コンストラクタ」といい、constructorを用いて、以下のように定義します。

```javascript:member.js
class member{
    constructor(){              //コンストラクタの定義
    }
}

const member1 = new member();
const member2 = new member();
```

コンストラクタでは、インスタンスの情報を格納するプロパティを定義できます。
例えば、インスタンスmember1の名前が"トム"で、年齢が15歳の場合、

```javascript:member.js
class member{
    constructor(name, age){
        this.name = name;  //プロパティと値の定義
        this.age = age;
    }
}

const member1 = new member("トム",15);  //値をコンストラクタに渡す
```

ここで、最後の行のmemberの引数の値がconstructorの引数に代入されます。
そして、this.nameとthis.ageは、それぞれクラスmember内で使用できるプロパティです。

次に、「メソッド」についてです。
コンストラクタではインスタンスの情報の格納を行ったのに対し、メソッドは、インスタンスに関する処理（自己紹介など）を行います。
例えば、上で出てきたトムが自己紹介するメソッドintroduceの場合、以下のように定義し、（インスタンス名）.（メソッド名）で実行します。

```javascript:member.js
class member{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    introduce(){           //メソッドintroduce()の定義
        console.log(`${this.name}です。${this.age}歳です。`);
}

const member1 = new member("トム",15);
member1.introduce();  //メソッドの実行
```

#クラスの継承とオーバーライド

学級のメンバーの中には、先生と生徒が含まれますが、生徒にのみ、名前と年齢に加えて所属する部活の情報も格納する場合を考えます。
まず、生徒のみのデータと処理をまとめたクラスstudentを定義します。
この際、以下のようにextendsを用いると、上で定義したクラスmemberの中身をそのままstudentに引き継ぐことができます。

```javascript:member.js
class student extends member{}  //クラスmemberを継承
```

これをクラスの「継承」といい、継承元のクラスを「親クラス」、継承先のクラスを「子クラス」と言います。
クラスを継承することで、子クラスのインスタンスにも親クラスのメソッドを適用することができます。

```javascript:member.js
class member{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    introduce(){
        console.log(`${this.name}です。${this.age}歳です。`);
}

class student extends member{}

const student1 = new student("トム",15);  //子クラスのインスタンスstudent1を生成
student1.introduce();  //親クラスのintroduceを実行
```

また、子クラスでも同様に、メソッドを定義することができます。
ここで、下のように、親クラスと同じメソッド名で定義してメソッドを実行した場合、どちらのクラスのメソッドが適用されるのでしょうか。

```javascript:member.js
class member{
    ...
    introduce(){  //親クラスのメソッド
        console.log(`${this.name}です。${this.age}歳です。`);
}

class student extends member{
    introduce(){  //子クラスのメソッド
        console.log(`${this.name}です。${this.age}歳です。`);
        console.log("野球部に所属しています。");
    }

const student1 = new student("トム",15);
student1.introduce();  //どちらのクラスのメソッドが実行される？
```

正解は、子クラスのメソッド（上の場合、student.introdue()）が適用されます。
このように、親クラスて定義されたメソッドを子クラスのメソッドで塗り替えることを、メソッドの「オーバーライド」と言います。

また、このオーバーライドは、コンストラクタについても同様に適用されます。
この時は、以下のように、super()を用いて親クラスのコンストラクタを呼び出し、その後に新しいプロパティclubを追加します。

```javascript:member.js
class member{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    ...
}

class student extends member{
    constructor(name, age, club){
        super(name, age);  //親クラスのコンストラクタの呼び出し
        this.club = club;  //プロパティclubを追加
    }
    introduce(){
    console.log(`${this.name}です。${this.age}歳です。`);
        console.log(`${this.club}部に所属しています。`);
}

const student1 = new student("トム",15);
student1.introduce("トム", 15, "野球");
```

以上のようにして、コンストラクタのオーバーライドもすることができます。

#まとめ

今回は、javascriptのクラスの定義やコンストラクタ、メソッド、継承、オーバーライドについて学級のメンバーを例にとってまとめました。
今回は基本的なところだけを書きましたが、また新しく勉強したことがあれば更新・修正したいと思います。