[JavaScript] ES6 クラス構文のマスタリング - クラスの宣言、初期化、メソッドの定義、継承など

ES6(ES2015)において、JavaScriptのクラス構文が導入されました。それ以前は、JavaScriptにおけるオブジェクト指向プログラミングは主に関数やプロトタイプを使用して達成されていました。しかし、クラス構文の導入により、オブジェクト指向プログラミングが直感的になり、明確に表現されるようになりました。

クラスの利用の根拠と利点

  • 直感性: JavaScriptのクラス構文は他のオブジェクト指向言語のクラスに似ており、開発者にとってより馴染み深く、理解しやすくなっています。
  • 再利用性: クラスや継承を活用することで、コードの再利用性を大幅に向上させることができます。
  • モジュラリティ: コードの構造をより組織的に管理できます。

基本的な構文

クラスの宣言

JavaScriptにおいて、クラスはclassキーワードを使用して宣言されます。

javascript
class Person {}

コンストラクタメソッドを用いた初期化

constructorメソッドは、クラスのインスタンスが作成されるときに呼び出される特別なメソッドです。このメソッドを使用することで、インスタンスの初期状態を設定することができます。

javascript
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

上記のコードでは、人物クラスは名前と年齢の2つの属性を持っています。このクラスのインスタンスをnewキーワードを使用して作成すると、constructorメソッドが呼び出され、与えられた名前と年齢がインスタンスに設定されます。

javascript
const JohnDoe = new Person('ジョン・ドウ', 25);
console.log(JohnDoe.name);  // ジョン・ドウ

メソッドの定義

クラスの中で、関数はメソッドとして定義することができます。これらのメソッドは、クラスのインスタンスで呼び出すことができます。

javascript
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  introduce() {
    console.log(`私の名前は${this.name}で、${this.age}歳です。`);
  }
}

インスタンスメソッドと静的メソッド

  • インスタンスメソッド: クラスのインスタンスで呼び出されるメソッド。上記の自己紹介メソッドがその例です。
  • 静的メソッド: staticキーワードを使用して定義されるこれらのメソッドは、インスタンスを作成せずにクラス自体で呼び出されます。

javascript
class Person {
  static populationCount() {
    console.log('人類は何十億もいます。');
  }
}

前述のPersonクラスのintroduceメソッドは次のように呼び出すことができます:

javascript
const JohnDoe = new 人物('ジョン・ドウ', 25);
JohnDoe.introduce();  // 私の名前はジョン・ドウで、25歳です。

静的メソッドpopulationCountは、インスタンスを作成せずにクラス名を使用して直接呼び出すことができます。

javascript
Person.populationCount();  // 人類は何十億もいます。

継承と拡張

JavaScriptにおけるクラスの継承は、既存のクラスからの属性やメソッドが新しいクラスに伝達される仕組みを示します。これにより、コードの再利用性が向上し、クラス間の階層的な関係の確立が容易になります。

継承の概念の理解

JavaScriptのクラスでの継承は、extendsキーワードを使用して実装されます。

javascript
class Animal {
  makeSound() {
    console.log('動物の声');
  }
}

class Dog extends Animal {

}

継承を使用することで、子クラスは親クラスのすべての属性

やメソッドを継承します。上記の例では、DogクラスはAnimalクラスからすべてのメソッドや属性を継承しています。

継承を通じたコードの再利用性

継承を利用することで、親クラスに共通のロジックやデータ構造を定義し、子クラスには固有の機能や属性のみを追加することができます。これにより、コードの重複が減少し、開発の効率とメンテナンスの容易性が向上します。

メソッドのオーバーライド

子クラスは、同じ名前の親クラスのメソッドを再定義することができます。これはメソッドのオーバーライドとして知られています。オーバーライドされたメソッドは、親クラスの元のメソッドを置き換えます。

javascript
class Animal {
  makeSound() {
    console.log('動物の声');
  }
}

class Dog extends Animal {
  makeSound() {
    console.log('ワン');
  }
}

const puppy = new Dog();
puppy.makeSound();  // ワン

superキーワードを使用して親クラスのメソッドを呼び出す

superキーワードを使用すると、子クラス内から親クラスのメソッドを呼び出すことができます。

javascript
class Dog extends Animal {
  makeSound() {
    super.makeSound();
    console.log('ワン');
  }
}

const puppy = new Dog();
puppy.makeSound();  
// 動物の声
// ワン

コンストラクタのオーバーライド

派生クラスにおいて、基底クラスのコンストラクタをオーバーライドすることは可能です。しかしながら、派生クラスのコンストラクタ内でsuperが呼び出されない場合、エラーが発生します。

派生クラスのコンストラクタ内でsuperキーワードを使用することにより、基底クラスのコンストラクタを呼び出すことができます。これにより、基底クラスでの必要な初期化作業を容易に行えます。

javascript
class Animal {
  constructor(name) {
    this.name = name;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}


const puppy = new 犬('ポチ', 'プードル');
console.log(puppy.name);   // ポチ
console.log(puppy.breed); // プードル

アクセス修飾子

JavaScriptのクラスで使用されるアクセス修飾子を深く探ることで、データやメソッドへのアクセスを制限します。

Public, Private, Protected

アクセス修飾子は、クラスメンバー(属性やメソッド)のアクセシビリティを決定します。これにより、クラスの内部実装を隠蔽したり、特定のメンバーへの制限されたアクセスを許可することで、オブジェクト指向プログラミングのカプセル化の原則を維持します。

  • Public: 既定では、すべてのメンバーは公開であり、どこからでもアクセスできます。
  • Private: # シンボルやアンダースコア(_)で始まるメンバーは非公開であり、クラス内でのみアクセスできます。
  • Protected: 現在、JavaScriptは正式に保護アクセス修飾子をサポートしていません。しかし、アンダースコア(_)の慣例を使用することで、クラスおよびそのサブクラス内でアクセス可能なことを効果的に模倣します。

アンダースコア(_) と # のプライベートメンバ変数とメソッドの使用

javascript
class 例 {
  _protectedMember = "保護として使用可能です。";
  #privateMember = "これは非公開変数です。";

  _protectedMethod() {
    console.log("このメソッドは保護として利用できます。");
  }

  #privateMethod() {
    console.log("これは非公開のメソッドです。");
  }
}

ゲッターとセッターのメソッド

ゲッターとセッターのメソッドは、オブジェクトの属性へのアクセスと変更の操作をカプセル化します。これにより、オブジェクトの内部データへの安全なアクセスや特定のロジックの実行が保証されます。

ゲッターとセッターのメソッドの定義と使用

javascript
class Person {
  constructor(name) {
    this._name = name;
  }

  get name() {
    return this._name;
  }

  set name(value) {
    this._name = value;
  }
}

const taro = new Person("太郎");
console.log(taro.name); // 太郎
taro.name = "花子";
console.log(taro.name); // 花子

静的メンバ

静的メンバはクラス自体に属し、どのインスタンスにも属さない。これらは、クラス全体で共有される属性やメソッドの作成時に使用される。

クラスレベルでの静的変数とメソッドの定義

javascript
class Math {
  static PI = 3.141592;

  static circleArea(radius) {
    return this.PI * radius * radius;
  }
}

console.log(Math.PI);       // 3.141592
console.log(Math.circleArea(5)); // 約 78.5398

静的メソッドとインスタンスメソッドの違いと応用

静的メソッドはクラスレベルで呼び出され、インスタンスの特定の状態に関係なく操作が必要な場合に利用されます。一方、インスタンスメソッドはオブジェクトの内部状態に基づいて動作し、オブジェクトのデータにアクセスしたり変更したりします。


JavaScriptに関連するクラスの多様な特徴は、オブジェクト指向プログラミングのパラダイムを効果的に実装するのに役立ちます。これらの特徴を適切に活用することで、コードの再利用性、拡張性、および保守性が向上します。これらの堅牢なJavaScriptクラスの特徴を効果的に活用して、効率的なプログラミングを行うことを期待しています。


© Copyright 2023 CLONE CODING