アルアカ - Arcadia Academia

Arcadia Academiaは「エンジニアリングを楽しむ」を合言葉に日本のデジタル競争力を高めることをミッションとするテックコミュニティです。

TypeScriptにおけるクラスと継承の使い方

Featured image of the post

TypeScriptは、オブジェクト指向プログラミング(OOP)に基づいたクラス継承をサポートしています。これにより、再利用可能で保守性の高いコードを記述することが可能です。JavaScriptのクラスに加えて、TypeScriptでは静的型付けやアクセス修飾子が追加されており、より強力で安全なオブジェクト指向の開発が可能です。本記事では、TypeScriptでのクラスと継承の基本的な使い方を解説します。

1. クラスの基本構文

TypeScriptのクラスは、プロパティメソッドを持つオブジェクトを定義するためのテンプレートです。以下は、クラスの基本的な例です。

typescript
コードをコピーする
class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet(): void {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
}

const person1 = new Person("Alice", 30);
person1.greet(); // "Hello, my name is Alice and I am 30 years old."

プロパティ

クラスのプロパティは、クラス内のメンバー変数で、nameageのように定義されます。型を指定することができ、クラスのインスタンスごとに異なる値を持つことができます。

typescript
コードをコピーする
name: string;
age: number;

コンストラクタ

コンストラクタはクラスのインスタンスが生成されるときに呼び出され、プロパティの初期化を行います。constructorメソッド内で、thisキーワードを使ってインスタンスのプロパティにアクセスします。

typescript
コードをコピーする
constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
}

メソッド

クラスのメソッドは、オブジェクトの動作を定義します。greetメソッドは、Personインスタンスに対して実行される振る舞いを示しています。

typescript
コードをコピーする
greet(): void {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}

2. アクセス修飾子(public, private, protected)

TypeScriptでは、クラスのプロパティやメソッドにアクセス修飾子を使って、外部からのアクセス範囲を制御できます。

public(デフォルト)

publicは、クラスの外部からもアクセスできることを意味します。何も指定しない場合は、publicがデフォルトで適用されます。

typescript
コードをコピーする
class Person {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }
}

const person = new Person("Alice");
console.log(person.name); // "Alice"

private

privateは、クラス内部からのみアクセスできるプロパティやメソッドを指定します。外部やサブクラスからはアクセスできません。

typescript
コードをコピーする
class Person {
    private age: number;

    constructor(age: number) {
        this.age = age;
    }

    private getAge(): number {
        return this.age;
    }
}

const person = new Person(30);
// console.log(person.age); // エラー: 'age'はprivate
// person.getAge(); // エラー: 'getAge'はprivate

protected

protectedは、クラス内部と、そのクラスを継承したサブクラスからアクセス可能です。privateと異なり、サブクラスでのアクセスが許可されています。

typescript
コードをコピーする
class Person {
    protected name: string;

    constructor(name: string) {
        this.name = name;
    }
}

class Employee extends Person {
    private salary: number;

    constructor(name: string, salary: number) {
        super(name);
        this.salary = salary;
    }

    display(): void {
        console.log(`${this.name} earns ${this.salary}.`);
    }
}

const employee = new Employee("Bob", 50000);
employee.display(); // "Bob earns 50000"

3. クラスの継承

TypeScriptでは、extendsキーワードを使って、クラスを継承することができます。継承を使うと、あるクラスの機能を別のクラスに引き継ぎ、新たな機能を追加することができます。

基本的な継承の例
typescript
コードをコピーする
class Animal {
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    makeSound(): void {
        console.log(`${this.name} makes a sound.`);
    }
}

class Dog extends Animal {
    constructor(name: string) {
        super(name); // 親クラスのコンストラクタを呼び出す
    }

    bark(): void {
        console.log(`${this.name} barks.`);
    }
}

const dog = new Dog("Rex");
dog.makeSound(); // "Rex makes a sound."
dog.bark(); // "Rex barks."

この例では、DogクラスがAnimalクラスを継承しています。DogクラスはAnimalクラスのnameプロパティとmakeSoundメソッドを引き継ぎ、さらにbarkメソッドを追加しています。

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

サブクラスでは、親クラスのメソッドをオーバーライド(上書き)することができます。superを使うことで、親クラスのメソッドを呼び出しつつ、新しい挙動を追加できます。

typescript
コードをコピーする
class Animal {
    makeSound(): void {
        console.log("Animal makes a sound.");
    }
}

class Dog extends Animal {
    makeSound(): void {
        super.makeSound(); // 親クラスのメソッドを呼び出す
        console.log("Dog barks.");
    }
}

const dog = new Dog();
dog.makeSound();
// "Animal makes a sound."
// "Dog barks."

この例では、DogクラスがAnimalクラスのmakeSoundメソッドをオーバーライドしています。super.makeSound()を呼び出すことで、親クラスのメソッドを実行し、その後にDog独自の振る舞いを追加しています。

4. 静的メンバー(static)

クラスのメソッドやプロパティを静的メンバーにすることもできます。staticキーワードを使うと、クラスそのものに紐づけられるメンバーを定義できます。静的メンバーはインスタンスではなく、クラス名から直接アクセスします。

typescript
コードをコピーする
class Calculator {
    static add(a: number, b: number): number {
        return a + b;
    }
}

console.log(Calculator.add(5, 10)); // 15

この例では、addメソッドが静的メソッドとして定義されています。インスタンスを作成せずに、クラス名を通じて直接呼び出すことができます。

5. 抽象クラス(abstract)

抽象クラスは、直接インスタンスを作成できないクラスで、サブクラスに必ず実装させるべきメソッドを定義できます。抽象クラスは、abstractキーワードで定義され、サブクラスで具体的に実装されるべき抽象メソッドを含みます。

typescript
コードをコピーする
abstract class Animal {
    abstract makeSound(): void;

    move(): void {
        console.log("Animal moves.");
    }
}

class Dog extends Animal {
    makeSound(): void {
        console.log("Dog barks.");
    }
}

const dog = new Dog();
dog.makeSound(); // "Dog barks."
dog.move(); // "Animal moves."

この例では、Animalクラスが抽象クラスで、makeSoundメソッドが抽象メソッドとして定義されています。Dogクラスがこの抽象クラスを継承し、makeSoundメソッドを実装しています。

まとめ

TypeScriptのクラスと継承は、オブジェクト指向プログラミングを強力にサポートする機能です。クラスを使ってコードを整理し、継承によって共通の機能を再利用することで、コードの冗長性を減らし、保守性を向上させることができます。また、アクセス修飾子や抽象クラス、静的メンバーなどの機能を活用することで、より安全で効率的な開発が可能です。



▼ 目次