HTML、CSS、JavaScriptJavaScriptの基礎

JavaScriptの基礎:オブジェクト指向を解説

JavaScriptオブジェクト指向解説ページのアイキャッチ画像 HTML、CSS、JavaScript

この記事では、オブジェクト指向プログラミングのクラスの定義方法、カプセル化、継承、モジュールの使用方法、そしてオブジェクト指向構文の高度なテーマについて、具体的なコード例を交えて理解を深めることができます。これらの知識は、効果的なオブジェクト指向プログラミングの基礎となります。

はじめに

この記事のコードをコピペして出力してみよう。

VSCodeでコードを書き、Node.jsでコンソール出力する方法がおすすめです。

クラスの基本

クラスは、オブジェクトの設計図や雛形のようなものです。クラスを使うことで、同じ構造や振る舞いを持つオブジェクトを簡単に作成できます。

JavaScript
// Personクラスの定義
class Person {
  // コンストラクタ(オブジェクト生成時に呼ばれる)
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

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

// Personクラスのインスタンスを作成
const person1 = new Person("太郎", 30);
person1.introduce(); // 出力: 私の名前は太郎で、30歳です。

出力結果:

私の名前は太郎で、30歳です。

このコードでは、Personクラスを定義しています。constructorメソッドはオブジェクトの初期化を行い、introduceメソッドは自己紹介文を出力します。newキーワードを使ってクラスのインスタンスを作成し、そのメソッドを呼び出しています。

コードの解説

クラスの定義:

JavaScript
class Person {
 // クラスの内容
}
  • class キーワードを使用して Person クラスを定義しています。
  • クラスは、オブジェクトの設計図やテンプレートのようなものです。

コンストラクタの定義:

JavaScript
constructor(name, age) {
 this.name = name;
 this.age = age;
}
  • constructor はクラスのインスタンスが作成されるときに自動的に呼び出される特別なメソッドです。
  • nameage はコンストラクタのパラメータです。
  • this は、作成されるインスタンス自身を指します。
  • this.name = namethis.age = age で、インスタンスのプロパティを初期化しています。

メソッドの定義:

JavaScript
introduce() {
 console.log(`私の名前は${this.name}で、${this.age}歳です。`);
}
  • introduce はクラスのメソッド(関数)です。
  • このメソッドは、インスタンスの nameage を使用して自己紹介文を出力します。
  • ${}テンプレートリテラルで、文字列内に変数を埋め込むために使用されます。

クラスのインスタンス化:

JavaScript
const person1 = new Person("太郎", 30);
  • new キーワードを使用して、Person クラスの新しいインスタンスを作成しています。
  • "太郎"30 がコンストラクタに渡される引数です。
  • 作成されたインスタンスは person1 変数に代入されます。

メソッドの呼び出し:

JavaScript
person1.introduce();
  • person1 インスタンスの introduce メソッドを呼び出しています。
  • これにより、コンソールに自己紹介文が出力されます。

重要なポイント:

  • クラスは、オブジェクト指向プログラミングの基本的な構成要素です。
  • コンストラクタは、新しいインスタンスの初期化を担当します。
  • メソッドは、クラスのインスタンスが持つ機能(関数)です。
  • this キーワードは、現在のインスタンスを参照するために使用されます。
  • インスタンス化は、クラスの設計図を基に実際のオブジェクトを作成するプロセスです。

このコードは、JavaScriptにおけるクラスの基本的な構造と使用方法を示しています。クラスを使用することで、関連するデータ(プロパティ)と機能(メソッド)をカプセル化し、コードの構造化と再利用性を向上させることができます。

カプセル化

カプセル化は、オブジェクトの内部データを外部から直接アクセスできないようにし、メソッドを通じてのみ操作可能にする概念です。JavaScriptでは、慣習的に_(アンダースコア)をプレフィックスとして使用して、プライベートなプロパティやメソッドを表現します。

JavaScript
class BankAccount {
  constructor(initialBalance) {
    this._balance = initialBalance; // プライベートプロパティ
  }

  // 残高を取得するメソッド
  getBalance() {
    return this._balance;
  }

  // 預金するメソッド
  deposit(amount) {
    if (amount > 0) {
      this._balance += amount;
      console.log(`${amount}円預金しました。残高: ${this._balance}円`);
    }
  }

  // 引き出すメソッド
  withdraw(amount) {
    if (amount > 0 && amount <= this._balance) {
      this._balance -= amount;
      console.log(`${amount}円引き出しました。残高: ${this._balance}円`);
    } else {
      console.log("引き出しできません。");
    }
  }
}

const account = new BankAccount(1000);
account.deposit(500);  // 出力: 500円預金しました。残高: 1500円
account.withdraw(200); // 出力: 200円引き出しました。残高: 1300円
console.log(account.getBalance()); // 出力: 1300

出力結果:

500円預金しました。残高: 1500円
200円引き出しました。残高: 1300円
1300

このコードでは、BankAccountクラスが銀行口座を表現しています。残高(_balance)は直接アクセスできないようにし、depositwithdrawメソッドを通じてのみ操作可能にしています。

コードの解説

クラスの定義:

JavaScript
class BankAccount {
  // クラスの内容
}
  • BankAccount クラスを定義しています。このクラスは銀行口座を表現します。

コンストラクタ:

JavaScript
constructor(initialBalance) {
 this._balance = initialBalance; // プライベートプロパティ
}
  • constructor はクラスのインスタンスが作成されるときに呼び出されます。
  • initialBalance は初期残高を表すパラメータです。
  • this._balance は残高を保持するプロパティです。
  • 先頭の _ はこのプロパティがプライベートであることを示す慣習です(実際には完全にプライベートではありません)。

残高取得メソッド:

JavaScript
getBalance() {
 return this._balance;
}
  • getBalance メソッドは現在の残高を返します。
  • これはカプセル化の一例で、プライベートな _balance にアクセスする方法を提供します。

預金メソッド:

JavaScript
deposit(amount) {
 if (amount > 0) {
   this._balance += amount;
   console.log(`${amount}円預金しました。残高: ${this._balance}円`);
  }
}
  • deposit メソッドは指定された金額を残高に追加します。
  • amount > 0 のチェックは、正の金額のみを受け入れるバリデーションです。

引き出しメソッド:

JavaScript
withdraw(amount) {
 if (amount > 0 && amount <= this._balance) {
   this._balance -= amount;
   console.log(`${amount}円引き出しました。残高: ${this._balance}円`);
 } else {
   console.log("引き出しできません。");
 }
}
  • withdraw メソッドは指定された金額を残高から引き出します。
  • 条件文は、金額が正で、かつ現在の残高以下であることを確認します。

クラスのインスタンス化と使用:

JavaScript
const account = new BankAccount(1000);
account.deposit(500);
account.withdraw(200);
console.log(account.getBalance());
  • new BankAccount(1000) で1000円の初期残高を持つ新しい口座を作成します。
  • depositwithdraw メソッドを呼び出して、預金と引き出しを行います。
  • getBalance メソッドで最終的な残高を取得し、表示します。

重要なポイント:

  • カプセル化: _balance は直接アクセスされず、メソッドを通じて操作されます。
  • メソッド: クラス内の関数で、オブジェクトの振る舞いを定義します。
  • 条件文: メソッド内で使用され、不正な操作を防ぎます。
  • テンプレートリテラル: ` を使用し、文字列内に変数を埋め込みます。

このコードは、オブジェクト指向プログラミングの基本的な概念(カプセル化、メソッド、プロパティ)を示しています。BankAccount クラスは、実際の銀行口座の基本的な機能をモデル化しており、データ(残高)と操作(預金、引き出し)を一つのユニットにまとめています。

継承

継承は、既存のクラスを基に新しいクラスを作成する機能です。親クラスの機能を引き継ぎつつ、新しい機能を追加したり既存の機能を上書きしたりできます。

JavaScript
// 親クラス
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name}が鳴いています。`);
  }
}

// 子クラス
class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 親クラスのコンストラクタを呼び出す
    this.breed = breed;
  }

  speak() {
    console.log(`${this.name}が吠えています:ワンワン!`);
  }

  fetch() {
    console.log(`${this.name}がボールを取ってきました。`);
  }
}

const animal = new Animal("動物");
animal.speak(); // 出力: 動物が鳴いています。

const dog = new Dog("ポチ", "柴犬");
dog.speak(); // 出力: ポチが吠えています:ワンワン!
dog.fetch(); // 出力: ポチがボールを取ってきました。

出力結果:

動物が鳴いています。
ポチが吠えています:ワンワン!
ポチがボールを取ってきました。

この例では、Animalクラスを親クラスとし、Dogクラスがそれを継承しています。DogクラスはAnimalクラスのspeakメソッドをオーバーライド(上書き)し、新しいfetchメソッドを追加しています。

コードの解説

親クラス(基底クラス)の定義:

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

 speak() {
   console.log(`${this.name}が鳴いています。`);
 }
}
  • Animal は親クラス(基底クラス)です。
  • constructorname プロパティを初期化します。
  • speak メソッドは動物が鳴く動作を表現します。

子クラス(派生クラス)の定義:

JavaScript
class Dog extends Animal {
 // クラスの内容
}
  • extends キーワードを使用して、Dog クラスが Animal クラスを継承していることを示します。
  • DogAnimal の全てのプロパティとメソッドを継承します。

子クラスのコンストラクタ:

JavaScript
constructor(name, breed) {
 super(name); // 親クラスのコンストラクタを呼び出す
 this.breed = breed;
}
  • super(name) は親クラス(Animal)のコンストラクタを呼び出します。
  • this.breed = breedDog クラス特有の breed プロパティを追加しています。

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

JavaScript
speak() {
 console.log(`${this.name}が吠えています:ワンワン!`);
}
  • Dog クラスで speak メソッドを再定義(オーバーライド)しています。
  • これにより、Dog インスタンスの speak メソッドは親クラスの同名メソッドを上書きします。

子クラス固有のメソッド:

JavaScript
fetch() {
 console.log(`${this.name}がボールを取ってきました。`);
}
  • fetch メソッドは Dog クラス特有のメソッドです。

インスタンスの作成と使用:

JavaScript
const animal = new Animal("動物");
animal.speak(); // 出力: 動物が鳴いています。

const dog = new Dog("ポチ", "柴犬");
dog.speak(); // 出力: ポチが吠えています:ワンワン!
dog.fetch(); // 出力: ポチがボールを取ってきました。
  • AnimalDog クラスのインスタンスを作成しています。
  • それぞれのインスタンスでメソッドを呼び出しています。

重要なポイント:

  • 継承: 子クラスは親クラスの特性を引き継ぎます。
  • super: 親クラスのコンストラクタやメソッドを呼び出すために使用します。
  • メソッドのオーバーライド: 子クラスで親クラスのメソッドを再定義できます。
  • ポリモーフィズム: 同じメソッド名(speak)でも、クラスによって異なる動作をします。

このコードは、オブジェクト指向プログラミングの重要な概念である継承ポリモーフィズムを示しています。Dog クラスは Animal クラスを継承することで基本的な特性を受け継ぎつつ、独自の特性や振る舞いを追加・変更しています。これにより、コードの再利用性と拡張性が向上します。

モジュール

モジュールは、コードを機能単位で分割し、再利用性を高めるための仕組みです。ES6以降のJavaScriptでは、exportimportを使ってモジュールを定義し、利用することができます。

※Node.jsでES Modulesを使用するには、以下の「package.json」ファイルをプロジェクトのルートディレクトリに追加してください。コードは以下の内容をコピペしてください。

package.json

JSON
{
  "type": "module"
}
javascriptにpackage.jsonファイル追加画面

「package.json」ファイルがない場合は以下のエラーが出ます。

(node:23000) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)

エラー内容:ES モジュールをロードするには、package.json で “type”: “module” を設定するか、.mjs 拡張子を使用するように警告がでます。

補足:

※ブラウザでES Modulesを使用するには、スクリプトタグにtype="module"属性を追加する必要があります。

HTML
<script type="module" src="main.js"></script>

math.js

JavaScript
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

main.js

JavaScript
import { add, subtract } from './math.js';

console.log(add(5, 3));      // 出力: 8
console.log(subtract(10, 4)); // 出力: 6

出力結果:

8
6

この例では、math.jsファイルで数学関連の関数をエクスポートし、main.jsファイルでそれらをインポートして使用しています。

math.jsの解説

関数のエクスポート:

JavaScript
export function add(a, b) {
 return a + b;
}

export function subtract(a, b) {
 return a - b;
}
  • export キーワードを使用して、関数を他のファイルから利用可能にしています。
  • add 関数は2つの数値を足し合わせます。
  • subtract 関数は1つの数値から別の数値を引きます。

main.jsの解説

モジュールのインポート:

JavaScript
import { add, subtract } from './math.js';
  • import 文を使用して、別のファイル(ここでは './math.js')からエクスポートされた関数をインポートしています。
  • { add, subtract } は、インポートする特定の関数を指定しています(名前付きインポート)。
  • './math.js' は、インポート元のファイルパスを示しています。

インポートした関数の使用:

JavaScript
console.log(add(5, 3));      // 出力: 8
console.log(subtract(10, 4)); // 出力: 6
  • インポートした addsubtract 関数を使用しています。
  • 結果をコンソールに出力しています。

重要なポイント:

  • モジュール: JavaScriptのモジュールシステムを使用しています。これにより、コードを別々のファイルに分割し、必要な部分だけをインポートできます。
  • エクスポート (export): 関数、オブジェクト、プリミティブ値などを他のモジュールで使用できるようにします。
  • インポート (import): 他のモジュールからエクスポートされたものを現在のモジュールで使用できるようにします。
  • 名前付きエクスポート/インポート: { } を使用して特定の項目をエクスポート/インポートします。
  • ファイルパス: './math.js'./ は現在のディレクトリを示します。

注意点:

  • このコードを実行するには、モジュールをサポートする環境(最新のブラウザ、Node.js、またはモジュールバンドラー)が必要です。
  • HTMLファイルで使用する場合、<script> タグに type="module" 属性を追加する必要があります。

このコードは、JavaScriptのモジュールシステムの基本的な使用方法を示しています。モジュールを使用することで、コードを整理し、再利用性を高め、名前空間の衝突を避けることができます。これは大規模なアプリケーションやライブラリの開発において特に重要です。

オブジェクト指向構文の高度な機能

オブジェクト指向プログラミングには、さらに高度な機能があります。

  • 静的メソッドとプロパティ: クラスのインスタンスを作成せずに使用できるメソッドやプロパティ。
  • ゲッターとセッター: プロパティの読み取りや設定をカスタマイズする特殊なメソッド。
  • 抽象クラスとインターフェース: 直接インスタンス化できない基底クラスや、メソッドの実装を強制する仕組み。
JavaScript
class MathOperations {
  static PI = 3.14159; // 静的プロパティ

  static circleArea(radius) { // 静的メソッド
    return this.PI * radius * radius;
  }

  constructor(value) {
    this._value = value;
  }

  get value() { // ゲッター
    return this._value;
  }

  set value(newValue) { // セッター
    if (newValue >= 0) {
      this._value = newValue;
    }
  }
}

console.log(MathOperations.PI); // 出力: 3.14159
console.log(MathOperations.circleArea(5)); // 出力: 78.53975

const math = new MathOperations(10);
console.log(math.value); // 出力: 10
math.value = 20;
console.log(math.value); // 出力: 20

出力結果:

3.14159
78.53975
10
20

このコードでは、静的プロパティ・メソッド、そしてゲッターとセッターの使用例を示しています。静的メンバーはクラス自体に属し、インスタンス化せずに使用できます。ゲッターとセッターは、プロパティのアクセスや変更時の振る舞いをカスタマイズするのに役立ちます。

コードの解説

クラスの定義:

JavaScript
class MathOperations {
 // クラスの内容
}
  • MathOperations クラスを定義しています。

静的プロパティ:

JavaScript
static PI = 3.14159;
  • static キーワードを使用して、クラスレベルのプロパティを定義しています。
  • この PI はインスタンスを作成せずに直接クラス名でアクセスできます。

静的メソッド:

JavaScript
static circleArea(radius) {
 return this.PI * radius * radius;
}
  • static キーワードを使用して、クラスレベルのメソッドを定義しています。
  • このメソッドもインスタンスを作成せずに直接クラス名で呼び出せます。

コンストラクタ:

JavaScript
constructor(value) {
 this._value = value;
}
  • クラスのインスタンスを作成する際に呼び出される特別なメソッドです。
  • _value はプライベートプロパティを示す慣習的な命名です(実際には完全にプライベートではありません)。

ゲッター(Getter):

JavaScript
get value() {
 return this._value;
}
  • get キーワードを使用して、プロパティの値を取得するメソッドを定義しています。
  • これにより、math.value のようにプロパティとしてアクセスできます。

セッター(Setter):

JavaScript
set value(newValue) {
 if (newValue >= 0) {
   this._value = newValue;
 }
}
  • set キーワードを使用して、プロパティの値を設定するメソッドを定義しています。
  • 条件文を使用して、負の値が設定されるのを防いでいます。

静的メンバーの使用:

JavaScript
console.log(MathOperations.PI);
console.log(MathOperations.circleArea(5));
  • 静的プロパティとメソッドは、クラス名を使って直接アクセス・呼び出しができます。

インスタンスの作成と使用:

JavaScript
const math = new MathOperations(10);
console.log(math.value);
math.value = 20;
console.log(math.value);
  • new キーワードを使ってクラスのインスタンスを作成しています。
  • ゲッターとセッターを使ってプロパティにアクセスしています。

重要なポイント:

  • 静的メンバー: クラスレベルで存在し、インスタンス化せずに使用できます。
  • ゲッター/セッター: プロパティのように見えますが、実際はメソッドです。これにより、値の取得や設定時に追加のロジックを実行できます。
  • カプセル化: ゲッターとセッターを使用することで、内部データ(_value)へのアクセスを制御しています。

このコードは、JavaScriptのクラスにおける高度な機能を示しています。静的メンバー、ゲッター、セッターの使用により、より柔軟で安全なクラス設計が可能になります。これらの機能は、オブジェクト指向プログラミングの重要な概念であるカプセル化とデータ隠蔽を実現するのに役立ちます。

以上が、JavaScriptのオブジェクト指向構文の基本と応用についての解説です。これらの概念を理解し適切に使用することで、より構造化され、保守性の高いコードを書くことができます。

まとめ

  • クラスの基本:クラスの定義方法、メンバ変数とメソッドの宣言について
  • カプセル化:データの隠蔽とアクセス制御の重要性
  • 継承:クラス間の階層関係と機能の再利用方法
  • モジュール:関連する機能をグループ化する方法
  • オブジェクト指向構文の高度な機能:より複雑なオブジェクト指向プログラミングの概念

この記事で学んだ知識を活用することで、オブジェクト指向プログラミングのスキルが大幅に向上し、より効果的で保守性の高いコードを書くことができるようになります。クラスの基本から高度な概念まで理解することは、現代のソフトウェア開発において不可欠なスキルです。

コメント

タイトルとURLをコピーしました