TypeScriptにおけるクラス

TypeScriptにおけるクラス

この記事ではTypeScriptにおけるクラスについて説明します。

YouTube Video

TypeScriptにおけるクラス

TypeScriptにおけるクラスは、JavaScriptのES6クラスをベースに、型注釈やアクセス修飾子などの追加機能を提供しています。これにより、オブジェクト指向プログラミングの概念を活用しつつ、より堅牢で明確な型安全性を確保することができます。

以下に、TypeScriptのクラスの基本的な使い方や特徴を説明します。

基本のクラス定義

 1class Person {
 2    name: string;  // Member variable
 3    age: number;   // Member variable
 4
 5    // Constructor
 6    constructor(name: string, age: number) {
 7        this.name = name;
 8        this.age = age;
 9    }
10
11    // Method
12    greet(): void {
13        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
14    }
15}
16
17const person = new Person("Alice", 25);
18person.greet();  // Hello, my name is Alice and I am 25 years old.
  • nameage はクラスのプロパティ(メンバ変数)です。
  • constructor はクラスのインスタンスを生成する際に呼ばれるメソッドで、引数を受け取りプロパティに値を代入します。
  • greet はクラスのメソッドで、void 型として戻り値がないことを示しています。

アクセス修飾子

TypeScriptでは、クラスのプロパティやメソッドに対して、アクセス制御を行うためのアクセス修飾子(publicprivateprotected)を使用できます。

public

デフォルトで、すべてのプロパティとメソッドは public です。これは、クラスの外部からもアクセスできることを意味します。

 1class Animal {
 2    public species: string;
 3
 4    constructor(species: string) {
 5        this.species = species;
 6    }
 7
 8    public makeSound(): void {
 9        console.log(`${this.species} makes a sound.`);
10    }
11}
12
13const animal = new Animal("Dog");
14console.log(animal.species);  // Dog
15animal.makeSound();           // Dog makes a sound.
  • speciesプロパティとmakeSoundメソッドはpublicとして宣言されており、クラスの外部からアクセスできます。

private

private 修飾子を使用すると、クラスの外部からそのプロパティやメソッドにアクセスできなくなります。

 1class Car {
 2    private brand: string;
 3
 4    constructor(brand: string) {
 5        this.brand = brand;
 6    }
 7
 8    public getBrand(): string {
 9        return this.brand;
10    }
11}
12
13const car = new Car("Toyota");
14// console.log(car.brand);  // Error: 'brand' is private and cannot be accessed.
15console.log(car.getBrand());  // Toyota
  • brandプロパティはprivateとして宣言されており、クラスの外部からはアクセスできません。
  • private 修飾子によってプロパティを隠蔽することにより、データのカプセル化を実現できます。

protected

protected 修飾子は、クラス外部からはアクセスできませんが、サブクラス(派生クラス)ではアクセスできます。

 1class Vehicle {
 2    protected model: string;
 3
 4    constructor(model: string) {
 5        this.model = model;
 6    }
 7}
 8
 9class Truck extends Vehicle {
10    public getModel(): string {
11        return this.model;
12    }
13}
14
15const truck = new Truck("Ford F-150");
16console.log(truck.getModel());  // Ford F-150
17
18// console.log(truck.model);
19// Error: Property 'model' is protected and only accessible within class 'Vehicle' and its subclasses.
  • modelプロパティはprotectedとして宣言されており、クラスの外部からはアクセスできませんが、サブクラスからはアクセスできます。

ゲッターとセッター

TypeScriptでは、プロパティの値を取得したり設定したりするために、getset キーワードを使ってゲッターとセッターを定義できます。

 1class Employee {
 2    private _salary: number;
 3
 4    constructor(salary: number) {
 5        this._salary = salary;
 6    }
 7
 8    // Getter
 9    get salary(): number {
10        return this._salary;
11    }
12
13    // Setter
14    set salary(newSalary: number) {
15        if (newSalary > 0) {
16            this._salary = newSalary;
17        } else {
18            console.log("Salary must be positive.");
19        }
20    }
21}
22
23const employee = new Employee(50000);
24console.log(employee.salary);  // 50000
25employee.salary = 60000;
26console.log(employee.salary);  // 60000
27employee.salary = -100;        // Salary must be positive.
  • この例では、salary プロパティに対してゲッターとセッターを使うことで、外部からのアクセスと更新を制御しています。セッターでは負の値が設定されないようにバリデーションを行い、不正な値が渡された場合には警告メッセージを表示しています。

継承

TypeScriptではクラスを継承することができます。extends キーワードを使って、親クラスの機能を引き継ぐことが可能です。

 1class Animal {
 2    constructor(public name: string) {}
 3
 4    public move(): void {
 5        console.log(`${this.name} is moving.`);
 6    }
 7}
 8
 9class Bird extends Animal {
10    public fly(): void {
11        console.log(`${this.name} is flying.`);
12    }
13}
14
15const bird = new Bird("Sparrow");
16bird.move();  // Sparrow is moving.
17bird.fly();   // Sparrow is flying.
  • この例では、Bird クラスが Animal クラスを継承することで、Animalmove メソッドを利用できます。さらに独自の fly メソッドを定義し、親クラスの機能を引き継ぎつつ、新たな機能を追加しています。

抽象クラス

抽象クラス(abstract)は、直接インスタンス化することはできず、サブクラスで具体的な実装を提供するためのテンプレートとして使われます。

 1abstract class Shape {
 2    abstract getArea(): number;
 3
 4    public describe(): void {
 5        console.log("This is a shape.");
 6    }
 7}
 8
 9class Circle extends Shape {
10    constructor(private radius: number) {
11        super();
12    }
13
14    public getArea(): number {
15        return Math.PI * this.radius * this.radius;
16    }
17}
18
19const circle = new Circle(5);
20console.log(circle.getArea());  // 78.53981633974483
21circle.describe();  // This is a shape.
  • この例では、Shape は抽象クラスとして定義されており、getArea はサブクラスで必ず実装すべき抽象メソッドです。Circle クラスはこの抽象クラスを継承し、独自に getArea メソッドを実装することで、円の面積を計算できるようにしています。また、describe のような具象メソッドは共通の機能として継承され、そのまま利用できます。

インターフェースとの関係

クラスはインターフェースを実装することができ、これにより特定のプロパティやメソッドを持つことを保証できます。

 1interface Flyable {
 2    fly(): void;
 3}
 4
 5class Airplane implements Flyable {
 6    public fly(): void {
 7        console.log("The airplane is flying.");
 8    }
 9}
10
11const airplane: Flyable = new Airplane();
12airplane.fly();  // The airplane is flying.
  • この例では、Flyable インターフェースで fly メソッドの仕様を定めており、Airplane クラスはこのインターフェースを実装することで fly メソッドを具体的に定義しています。これにより、Flyable 型として扱えるオブジェクトは必ず fly メソッドを持つことが保証されます。

スタティックメンバー

クラス内にスタティックメンバーを定義すると、そのメソッドやプロパティはクラス自体に紐づきます。スタティックメンバーはインスタンス化することなく呼び出せます。

 1class MathUtils {
 2    static PI: number = 3.14;
 3
 4    static add(a: number, b: number): number {
 5        return a + b;
 6    }
 7}
 8
 9console.log(MathUtils.add(10, 20)); // 30
10console.log(MathUtils.PI); // 3.14
  • staticキーワードを使ってスタティックメソッドを定義します。
  • この例では、MathUtilsクラスにスタティックメソッドaddとスタティックプロパティPIを定義しています。
  • スタティックメンバーはクラスインスタンスには属さず、クラス自体から直接呼び出されます。

まとめ

TypeScriptのクラスは、JavaScriptのクラス機能に型安全性やアクセス修飾子、抽象クラスといった追加機能を提供します。これにより、オブジェクト指向プログラミングがより強力かつ安全に行えます。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video