TypeScriptで継承、プライベートコンストラクタ、ジェネリクスを使用してクラスコンストラクタをさらに活用する
TypeScriptにおけるクラスコンストラクタ型:詳細解説
コンストラクタ型は、コンストラクタの引数と戻り値の型を定義するための仕組みです。これにより、クラスインスタンスがどのように作成されるかをより厳密に制御することができます。
コンストラクタ型を使用する利点は次のとおりです。
- 型安全性: コンストラクタの引数と戻り値の型を定義することで、型エラーを防ぎ、コードの信頼性を高めることができます。
- コードの可読性: コンストラクタの引数と戻り値の型を明確に示すことで、コードを読んでいる他の開発者がその意図をより簡単に理解することができます。
- 再利用性: コンストラクタ型を定義することで、同じようなインスタンスを生成するコードを再利用することができます。
コンストラクタ型は、次のような構文で定義されます。
constructor(parameters: ParameterType, returnType?: ReturnType): void;
parameters
: コンストラクタの引数の型を定義します。returnType
: コンストラクタの戻り値の型を定義します。void
を指定すると、コンストラクタが値を返さないことを意味します。
例:
class Person {
constructor(name: string, age: number) {}
}
let person: Person = new Person('John Doe', 30);
この例では、Person
クラスのコンストラクタは、name
(文字列) と age
(数値) という 2 つの引数を取ります。コンストラクタは値を返しません。
コンストラクタ型の高度な機能
コンストラクタ型には、より高度な機能もいくつかあります。
- オプションのプロパティ: オプションのプロパティを定義するには、
?
記号を使用します。
class Person {
constructor(name: string, age?: number) {}
}
この例では、age
プロパティはオプションであることを意味します。
- デフォルト値: デフォルト値を定義するには、
=
記号を使用します。
class Person {
constructor(name: string, age = 30) {}
}
この例では、age
プロパティのデフォルト値は 30 です。
- レストパラメータ: レストパラメータを使用するには、
...
記号を使用します。
class Person {
constructor(name: string, ...skills: string[]) {}
}
この例では、skills
プロパティは、任意の数の文字列を受け取ることができます。
その他の注意点
- コンストラクタは、継承されたクラスでオーバーライドすることができます。
- コンストラクタは、プライベートにすることができます。
コンストラクタ型は、TypeScript クラスのインスタンスを生成する方法をより厳密に制御するための強力なツールです。コンストラクタ型の利点と構文を理解することで、より型安全で読みやすく、再利用可能なコードを書くことができます。
TypeScriptにおけるクラスコンストラクタ型の例
例 1: 基本的なコンストラクタ型
class Person {
constructor(name: string, age: number) {}
}
let person1 = new Person('John Doe', 30);
let person2 = new Person('Jane Doe', 25);
例 2: オプションのプロパティとデフォルト値
class Person {
constructor(name: string, age?: number, hobbies?: string[]) {}
}
let person1 = new Person('John Doe'); // age and hobbies are undefined
let person2 = new Person('Jane Doe', 30); // age is 30, hobbies are undefined
let person3 = new Person('Peter Jones', 25, ['programming', 'reading']); // age is 25, hobbies is ['programming', 'reading']
この例では、Person
クラスのコンストラクタには、name
(文字列) という必須引数と、age
(数値) と hobbies
(文字列の配列) という 2 つのオプションプロパティが定義されています。
例 3: レストパラメータ
class Person {
constructor(name: string, ...skills: string[]) {}
}
let person1 = new Person('John Doe', 'programming', 'reading');
let person2 = new Person('Jane Doe', 'writing', 'painting', 'music');
この例では、Person
クラスのコンストラクタには、name
(文字列) という必須引数と、skills
(文字列) というレストパラメータが定義されています。skills
パラメータは、任意の数の文字列を受け取ることができます。
例 4: コンストラクタのオーバーライド
class Person {
constructor(name: string) {}
}
class Student extends Person {
constructor(name: string, major: string) {
super(name); // 親クラスのコンストラクタを呼び出す
}
}
let student1 = new Student('John Doe', 'Computer Science');
この例では、Student
クラスは Person
クラスを継承しています。Student
クラスのコンストラクタは、name
(文字列) と major
(文字列) という 2 つの引数を取ります。コンストラクタは、super()
キーワードを使用して親クラスのコンストラクタを呼び出し、name
プロパティを初期化します。
例 5: プライベートコンストラクタ
class Person {
private constructor(name: string) {} // プライベートコンストラクタ
static create(name: string): Person {
return new Person(name); // プライベートコンストラクタを介してインスタンスを作成
}
}
let person1 = Person.create('John Doe');
この例では、Person
クラスのコンストラクタはプライベートに設定されています。つまり、クラス外部からは直接インスタンス化できません。代わりに、create()
という静的メソッドを使用してインスタンスを作成する必要があります。
例 6: ジェネリックコンストラクタ
class Box<T> {
constructor(private value: T) {}
getValue(): T {
return this.value;
}
}
let stringBox = new Box<string>('Hello');
let numberBox = new Box<number>(10);
この例では、Box
クラスはジェネリックです。つまり、任意の型を受け入れることができます。constructor()
メソッドは、value
プロパティに渡された値を格納します。getValue()
メソッドは、value
プロパティの値を返します。
これらの例は、TypeScriptにおけるクラスコンストラクタ型の基本的な使用方法を示すものです。コンストラクタ型は、より複雑なシナリオにも使用できます。
TypeScriptにおけるクラスコンストラクタ型の高度な使用方法
アクセス修飾子
コンストラクタには、アクセス修飾子を設定することができます。アクセス修飾子は、コンストラクタがどこから呼び出せるかを制御します。
public
: コンストラクタは、どこからも呼び出すことができます。これがデフォルトのアクセス修飾子です。private
: コンストラクタは、同じクラス内でのみ呼び出すことができます。
class Person {
public constructor(name: string) {} // public constructor
private constructor(name: string, age: number) {} // private constructor
protected constructor(name: string, age: number, hobbies: string[]) {} // protected constructor
}
この例では、Person
クラスには 3 つのコンストラクタが定義されています。
public constructor(name: string)
は、どこからも呼び出すことができます。private constructor(name: string, age: number)
は、Person
クラス内でのみ呼び出すことができます。
オーバーロード
コンストラクタをオーバーロードすることができます。オーバーロードとは、同じ名前を持つメソッドを複数定義し、それぞれ異なる引数リストを持つようにすることです。コンストラクタをオーバーロードすると、さまざまな方法でインスタンスを作成することができます。
class Person {
constructor(name: string); // 1つの引数を持つコンストラクタ
constructor(name: string, age: number); // 2つの引数を持つコンストラクタ
}
let person1 = new Person('John Doe'); // 1つの引数を持つコンストラクタを使用
let person2 = new Person('Jane Doe', 30); // 2つの引数を持つコンストラクタを使用
constructor(name: string)
は、name
(文字列) という 1 つの引数を取ります。
コンストラクタチェーンを使用して、親クラスのコンストラクタを呼び出すことができます。コンストラクタチェーンを使用すると、親クラスからインスタンスの状態を継承することができます。
class Person {
constructor(name: string) {}
}
class Student extends Person {
constructor(name: string, major: string) {
super(name); // 親クラスのコンストラクタを呼び出す
}
}
let student1 = new Student('John Doe', 'Computer Science');
静的コンストラクタは、クラスのインスタンスを作成せずに呼び出すことができるコンストラクタです。静的コンストラクタは、クラスに関する初期化情報を格納するために使用されます。
class Person {
private static nextId = 1;
constructor(public name: string) {
this.id = Person.nextId++;
}
}
let person1 = new Person('John Doe');
let person2 = new Person('Jane Doe');
console.log(person1.id); // 1
console.log(person2.id); // 2
この例では、Person
クラスには静的コンストラクタが定義されています。静的コンストラクタは、nextId
というプロパティを初期化します。nextId
プロパティは、各インスタンスに割り当てる ID を格納するために使用されます。
ジェネリックコンストラクタは、任意の型を受け入れることができるコンストラクタです。ジェネリックコンストラクタを使用すると、さまざまな種類のデータを持つインスタンスを作成することができます。
class Box<T> {
constructor(private value: T) {}
getValue(): T {
class typescript types