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."
プロパティ
クラスのプロパティは、クラス内のメンバー変数で、name
やage
のように定義されます。型を指定することができ、クラスのインスタンスごとに異なる値を持つことができます。
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のクラスと継承は、オブジェクト指向プログラミングを強力にサポートする機能です。クラスを使ってコードを整理し、継承によって共通の機能を再利用することで、コードの冗長性を減らし、保守性を向上させることができます。また、アクセス修飾子や抽象クラス、静的メンバーなどの機能を活用することで、より安全で効率的な開発が可能です。