[Day13] クラス part1

本記事は一人アドベントカレンダー企画の一つです。
[30代未経験エンジニアが25日後にJavaScriptをマスターするカレンダー](https://qiita.com/advent-calendar/2022)

[JAVASCRIPT.INFO](https://ja.javascript.info/)を元にJavaScriptを勉強していき、そこで学んだ知識をアウトプットしていきます。
２５日でJAVASCRIPT.INFOをやりきり、未経験エンジニアがJavaScriptをマスターする過程を投稿していきます。



## 9.1 クラス(Class) 基本構文
### 知らない単語
- 無し

### 学んだこと
- class構文

class構文の基本の書き方は以下の通りである
```javascript
class MyClass {
  // クラスメソッド
  constructor() { ... }
  method1() { ... }
  method2() { ... }
  method3() { ... }
  ...
}
```
constructor()は new により自動で呼び出され、オブジェクトを初期化できる事が重要

- クラスとは？

JavaScript ではクラスは関数の一種である

例えば下記のコードで
```javascript
class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

// 証拠: User は function
alert(typeof User); // function
```
class User {...} 構造が実際に行っている事は
User と言う名前の関数を作成し、関数コードは constructor メソッドであり、
User.prototype に、sayHi などのクラスメソッドを格納する

- クラス表現

関数と同じように、クラスも別の式の中で定義する、渡す、返却する、代入するなどの事ができる

### 感想
classはJavaScriptだけでなく、他の言語でも基本となる重要な要素だと思うので、十分な理解をした上で次に進みたいと思う。



## 9.2 クラスの継承
### 知らない単語
- オーバライドとは
    - ある場所で定義された設定や手続き、属性などを、別の定義で上書きする事


### 学んだこと
クラスの継承は、あるクラスが別のクラスを拡張するための方法、要は既存の機能の上に、新たな機能を作る事である

- “extends” キーワード

クラス Animal があるとして
```javascript
class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
  run(speed) {
    this.speed += speed;
    alert(`${this.name} runs with speed ${this.speed}.`);
  }
  stop() {
    this.speed = 0;
    alert(`${this.name} stopped.`);
  }
}

let animal = new Animal("My animal");
```
もう１つ class Rabbit を作成する
うさぎ(rabbit)は動物(animal)なので、Rabbit クラスは Animal がベースとなり、animal メソッドへアクセスできる
これで、animalが実行できることをrabbitも実行できるようになる

別のクラスを拡張する構文は class Child extends Parent である

コンストラクタをオーバーライドする時は
this を使う前に Child コンストラクタの中で super として親のコンストラクタを呼ぶ必要がある

他のメソッドをオーバーライドする時は
super.method() を使用することで、Child で親のメソッドを呼び出すことができる

内部:
メソッドは内部の [[HomeObject]] プロパティで自身のクラス/オブジェクトを保持している
なので、オブジェクトから別のオブジェクトへ super を持つメソッドをコピーするのは推奨されない


### 感想
クラスの継承、拡張してからオーバーライドする時の一連の流れを理解して的確に使えるようにしたい。


## 9.3 静的(static)プロパティとメソッド
### 知らない単語
- インスタンスとは
　　　　　- あらかじめ定義されたコンピュータプログラムやデータ構造などを、メインメモリ上に展開して処理・実行できる状態にしたもの


### 学んだこと
クラスは全体にメソッドを割り当てることもでき、そのメソッドは static(静的) と呼ぶ
クラス宣言時に static キーワードを付ける
このように
```javascript
class User {
  static staticMethod() {
    alert(this === User);
  }
}

User.staticMethod(); // true
```
プロパティとして直接割り当てるのと同じ事をしている
static メソッドは、クラスには属するが、特定のオブジェクトには属さない関数を実装するのに使用される

- 静的プロパティ

静的プロパティはクラスレベルのデータを格納するときに使用され、インスタンスにバインドされない
書き方は
```javascript
class MyClass {
  static property = ...;

  static method() {
    ...
  }
}
```
となり、技術的には、クラス自身への代入と同じなので静的プロパティは継承される


### 感想
クラスの使い方は多いので、間違えないようにしたい。また、静的プロパティはバインドされないので細かな所も忘れないようにする。


## 9.4 Private / protected プロパティとメソッド
### 知らない単語
- インタフェースとは
　　　　　- 2つの異なる機器やシステム、ソフトウェア間で情報のやり取りがなされる際、その間をつなぐ規格や機能


### 学んだこと
- 内部 / 外部インタフェース

オブジェクト指向プログラミングでは、プロパティとメソッドは 2つに分かれる
内部インタフェースはクラスの他のメソッドからアクセス可能だが、外側からはアクセスできないメソッドやプロパティの事
外部インタフェースは外部のクラスからもアクセス可能なメソッドやプロパティの事

JavaScript には以下のプロパティとメンバがある
パブリック(public): どこからでもアクセス可能、外部インタフェースである
プライベート(private): クラス内部からのみアクセスでき、内部インタフェース用である

- Supportable
コードは絶えず開発と改良されるので、
もし内部インタフェースを厳密に区切ると、クラスの開発者は利用者へ通知しなくても内部のプロパティとメソッドを自由に変更することができる
特定のメソッド名を変更したり、パラメータを変更したり、削除したりすることができると開発が簡単になる

新しいバージョンが登場した時に、利用者目線で見れば外部インタフェースが同じであればアップグレードは容易である

- 複雑さを隠す
基本的にプログラムもシンプルな方がよい
実装の詳細が隠されてる上で、シンプルで丁寧なドキュメント化をされた外部インタフェースであるのが望ましい
内部インタフェースを隠すためには、proctected または public プロパティを使用する

### 感想
常にコードはシンプルなものが求められるという事がよくわかる。
様々なメソッドや記述方法を使用するとシンプルな書き方がわからなくなると思うので、周りの詳しい人に聞いて練習していきたい。

# 最後に
この章で学んだ中ではやはりclassがとても重要だと思った。
今後、他の言語を勉強していく中で応用できる事も多いので、正しく理解していきたい。