🚗

オブジェクト指向がずっと曖昧だったので、整理して理解する

に公開

はじめに

プログラミングでよくつまずくオブジェクト指向。
クラス、メソッド、プロパティ...言葉は聞いたことあるけど、なんとなくの理解でモヤモヤしている人も多いと思います。
そこで今回は、基本用語と身近な例でわかりやすくまとめてみました。
オブジェクト指向をしっかり理解したい人の助けになれば嬉しいです!

用語整理

基本編🛠️

まずはオブジェクト指向でよく出てくる基本用語を整理します。

用語 意味 例(テーマ:車クラス)
クラス オブジェクトの設計図。属性やメソッドを定義する枠組み。 class Car { ... }(車の設計図)
オブジェクト(インスタンス) クラスから作られる実体。実際に動作やデータを持つもの。 const myCar = new Car();(1台の車を作る)
属性(フィールド) オブジェクトが持つデータ。JavaScriptでは「プロパティ」とも呼ばれる。 this.color = "red";(色の属性)
メソッド クラスに定義される関数。オブジェクトの動作を表す。 drive() { console.log("走行中"); }(走る動作)
コンストラクタ オブジェクト生成時に実行される初期化用のメソッド。 constructor(color) { this.color = color; }(色を設定)
this 現在のインスタンス自身を指すキーワード。 this.color(その車自身の色)
カプセル化 データと処理をまとめ、外部からの不正アクセスを防ぐ考え方。 #speed(プライベートな速度)+getSpeed()で取得
継承 既存クラスの機能を引き継ぎ、新たなクラスを作る仕組み。 class SportsCar extends Car { ... }(スポーツカーが車を継承)
super 親クラスのコンストラクタやメソッドを呼び出すキーワード。 super(color);(親クラスの色設定を呼ぶ)

応用編🚀

次に、少し応用的な用語を整理します。静的型付き言語でよく使われる概念も含みます。

用語 意味 例(テーマ:車クラス)
オーバーライド 親クラスのメソッドを子クラスで再定義すること。 drive() { console.log("高速走行中"); }(スポーツカーで上書き)
オーバーロード 同じ名前のメソッドを引数の数や型で使い分ける仕組み。※TypeScriptやJavaで使用される drive()drive(speed: number)(速度指定)
抽象クラス インスタンス化できず、子クラスに共通処理を提供するクラス。 abstract class Vehicle { abstract drive(); }(共通の枠組み)
インターフェース メソッドの定義だけを示し、実装は各クラスに任せる仕組み。 interface Electric { charge(): void; }(充電可能な車)
ポリモーフィズム 同じメソッド名でも、呼び出すオブジェクトによって異なる動作をする仕組み。 vehicle.drive() → 車は「走行中」、バイクは「バイク走行中」

使用例

ここからは、実際にJavaScript(一部TypeScript)での使い方をコードで見ていきましょう。

クラス

class Car {
  // 車の設計図(クラス)
}

オブジェクト(インスタンス)

const myCar = new Car();  // Carクラスから作られた1台の車(オブジェクト)

属性(フィールド)

class Car {
  constructor(color) {
    this.color = color;  // 色という属性
  }
}

メソッド

class Car {
  drive() {
    console.log("走行中");
  }
}

コンストラクタ

class Car {
  constructor(color) {
    this.color = color;  // オブジェクト生成時に色を設定
  }
}

this

class Car {
  constructor(color) {
    this.color = color;  // thisは「この車」の意味
  }
  showColor() {
    console.log(this.color);  // 自分の色を表示
  }
}

カプセル化

class Car {
  #speed = 0;  // プライベートな速度
  accelerate() {
    this.#speed += 10;
  }
  getSpeed() {
    return this.#speed;  // 外部からはこのメソッド経由でしかアクセスできない
  }
}

継承

class SportsCar extends Car {
  turboBoost() {
    console.log("ターボブースト開始!");
  }
}

super

class SportsCar extends Car {
  constructor(color) {
    super(color);  // 親クラスCarのコンストラクタを呼ぶ
  }
}

オーバーライド

class Car {
  drive() {
    console.log("走行中");  // 親クラスのメソッド
  }
}

class SportsCar extends Car {
  drive() {
    console.log("高速走行中");  // 親クラスのdriveを上書き(オーバーライド)
  }
}

const car = new SportsCar();
car.drive();  // 「高速走行中」と表示される

オーバーロード(※TypeScript)

class Car {
  drive(): void;
  drive(speed: number): void;
  drive(speed?: number): void {
    if (speed) {
      console.log(`${speed}kmで走行中`);
    } else {
      console.log("走行中");
    }
  }
}

const car = new Car();
car.drive();       // 「走行中」
car.drive(100);    // 「100kmで走行中」

抽象クラス(※TypeScript)

abstract class Vehicle {
  abstract drive(): void;  // 実装は子クラスに任せる
}

class Car extends Vehicle {
  drive() {
    console.log("車が走行中");
  }
}

const myCar = new Car();
myCar.drive();

インターフェース(※TypeScript)

interface Electric {
  charge(): void;
}

class ElectricCar implements Electric {
  charge() {
    console.log("充電中...");
  }
}

const tesla = new ElectricCar();
tesla.charge();

ポリモーフィズム

class Vehicle {
  drive() {
    console.log("乗り物が走行中");
  }
}

class Car extends Vehicle {
  drive() {
    console.log("車が走行中");
  }
}

class Bike extends Vehicle {
  drive() {
    console.log("バイクが走行中");
  }
}

const vehicles = [new Car(), new Bike()];
vehicles.forEach(vehicle => vehicle.drive());
// 出力:
// 車が走行中
// バイクが走行中

おわりに

オブジェクト指向は、最初は用語の多さに圧倒されがちですが、身近な例に置き換えて整理すれば、少しずつ理解が深まっていきます。
私は何度も挫折しそうになりましたが、あきらめずに向き合うことで、少しずつ理解できるようになってきました。
焦らず一歩ずつ、自分のペースでオブジェクト指向を身につけていきましょう!

Discussion