抽象クラスとインターフェイスの違い・使い分け

解説

抽象クラスは、基本的な機能を部分的に実装し、サブクラスがそれを継承して使うことを意図したクラスだ。一方、インターフェイスはクラスが「何ができるか」という契約を定義し、その機能は具体的に実装されない。

JavaScriptでの抽象クラスとインターフェイスの実装

抽象クラス

抽象クラスは、基本的なメソッドを持ちつつ、一部のメソッドはサブクラスで実装することを強制する。


// 抽象クラスとしてAnimalを定義
class Animal {
    constructor(name) {
        this.name = name;
    }

    makeSound() {
        throw new Error("このメソッドはサブクラスで実装される必要があります");
    }

    move() {
        console.log(this.name + " is moving");
    }
}

// サブクラスが抽象メソッドを実装する
class Dog extends Animal {
    makeSound() {
        console.log("ワンワン!");
    }
}

const myDog = new Dog("ポチ");
myDog.makeSound(); // 結果: ワンワン!
myDog.move();      // 結果: ポチ is moving
    

インターフェイス(JavaScript風)

JavaScriptにはインターフェイスは存在しないが、オブジェクトの構造やメソッドの契約を守るような設計ができる。以下の例では、canFlyの機能を持つクラスに「飛べる」という役割を与える。


// インターフェイスのように使う関数(Mixinパターン)
const canFly = {
    fly() {
        console.log(this.name + " is flying!");
    }
};

class Bird {
    constructor(name) {
        this.name = name;
    }
}

// BirdクラスにcanFly機能を追加
Object.assign(Bird.prototype, canFly);

const sparrow = new Bird("スズメ");
sparrow.fly(); // 結果: スズメ is flying!