アクセス修飾子 (access modifier)
JavaやPHPなどの言語では、フィールドやメソッドにprivate, protected, publicを指定できます。JavaScriptでもprivateのようなプロパティを実現するためにプライベートクラスフィールドという仕様が実験的に導入されはじめてはいますが、現状はJavaのようなアクセス修飾子はありません。TypeScriptにはJava風のアクセス修飾子があります。
| アクセス修飾子 | 説明 |
|---|---|
| (宣言なし) | publicと同等 |
| public | どこからもアクセス可能 |
| protected | 自身のクラスとサブクラスからアクセス可能 |
| private | 自身のクラスのみアクセス可能 |
アクセス修飾子を省略した場合はpublicになります。
アクセス修飾子は、フィールド、コンストラクタ、メソッドに宣言することができます。
public#
publicアクセス修飾子はどこからもアクセス可能です。
typescriptclass Animal {public name: string; // フィールドにpublicアクセス修飾子// コンストラクターにpublicアクセス修飾子public constructor(theName: string) {this.name = theName;}// メソッドにpublicアクセス修飾子public move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);// publicアクセス修飾子である`this.name`を使用することが可能}}
typescriptclass Animal {public name: string; // フィールドにpublicアクセス修飾子// コンストラクターにpublicアクセス修飾子public constructor(theName: string) {this.name = theName;}// メソッドにpublicアクセス修飾子public move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);// publicアクセス修飾子である`this.name`を使用することが可能}}
gorillaを実装し、動作を確認してみます。
typescriptconst gorilla = new Animal("ゴリラ");gorilla.move(10);//=> 'ゴリラ moved 10m.'gorilla.name = "ゴリラゴリラ";gorilla.move(20);//=> 'ゴリラゴリラ moved 20m.'
typescriptconst gorilla = new Animal("ゴリラ");gorilla.move(10);//=> 'ゴリラ moved 10m.'gorilla.name = "ゴリラゴリラ";gorilla.move(20);//=> 'ゴリラゴリラ moved 20m.'
nameプロパティはpublic宣言されているため、インスタンスされた変数(gorilla)からの読み書きが可能になっています。「ゴリラ」から「ゴリラゴリラ」に変更することができます。
protected#
protectedアクセス修飾子は自身のクラスとサブクラスからアクセス可能です。
Animalクラスmoveメソッドのアクセス修飾子をpublicからprotectedに変更しエラーを出してみます。
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`protected`に変更protected move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}const gorilla = new Animal("ゴリラ");gorilla.move(10); // error TS2339: Property 'move' does not exist on type 'Animal'.
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`protected`に変更protected move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}const gorilla = new Animal("ゴリラ");gorilla.move(10); // error TS2339: Property 'move' does not exist on type 'Animal'.
gorilla.move()メソッドはprotected宣言されているため、自身のクラスとサブクラスのみアクセスとなります。つまりインスタンスされたgorillaからはアクセスが拒否され、コンパイルエラーが発生します。
protectedで保護されたmove()メソッドを新たに実装し、10倍速く動くゴリラを作ってみます。
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`protected`に変更protected move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}class Gorilla extends Animal {move(distanceInMeters: number) {super.move(distanceInMeters * 10);}}const gorilla = new Gorilla("速いゴリラ");gorilla.move(10);//=> '速いゴリラ moved 100m.'
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`protected`に変更protected move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}class Gorilla extends Animal {move(distanceInMeters: number) {super.move(distanceInMeters * 10);}}const gorilla = new Gorilla("速いゴリラ");gorilla.move(10);//=> '速いゴリラ moved 100m.'
Animalスーパークラスを持つGorillaクラスを定義しmove()を実装しています。Gorillaクラスのmove()メソッド内でsuperキーワードを利用してスーパークラスのmove()メソッドを呼び出しています。
private#
privateアクセス修飾子は自身のクラスのみアクセス可能です。
protected move()をprivate move()に変更してみます。privateに変更されたことによりGorillaクラスのsuper.moveにアクセスすることが許されずエラーとなります。
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`private`に変更private move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}class Gorilla extends Animal {move(distanceInMeters: number) {super.move(distanceInMeters * 10); // Property 'move' is private and only accessible within class 'Animal'.}}
typescriptclass Animal {public name: string;public constructor(theName: string) {this.name = theName;}// `public`から`private`に変更private move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}class Gorilla extends Animal {move(distanceInMeters: number) {super.move(distanceInMeters * 10); // Property 'move' is private and only accessible within class 'Animal'.}}
privateメソッドの多くの使い方としては、自身のクラス内の長いコードを機能別に分ける時に利用します。