メインコンテンツまでスキップ

アクセス修飾子 (access modifier)

JavaやPHPなどの言語では、フィールドやメソッドにprivate, protected, publicを指定できます。JavaScriptでもprivateのようなプロパティを実現するためにプライベートクラスフィールドという仕様が実験的に導入されはじめてはいますが、現状はJavaのようなアクセス修飾子はありません。TypeScriptにはJava風のアクセス修飾子があります。

アクセス修飾子説明
(宣言なし)publicと同等
publicどこからもアクセス可能
protected自身のクラスとサブクラスからアクセス可能
private自身のクラスのみアクセス可能

アクセス修飾子を省略した場合はpublicになります。

アクセス修飾子は、フィールド、コンストラクタ、メソッドに宣言することができます。

public#

publicアクセス修飾子はどこからもアクセス可能です。

typescript
class 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`を使用することが可能
}
}
typescript
class 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を実装し、動作を確認してみます。

typescript
const gorilla = new Animal("ゴリラ");
gorilla.move(10);
//=> 'ゴリラ moved 10m.'
gorilla.name = "ゴリラゴリラ";
gorilla.move(20);
//=> 'ゴリラゴリラ moved 20m.'
typescript
const gorilla = new Animal("ゴリラ");
gorilla.move(10);
//=> 'ゴリラ moved 10m.'
gorilla.name = "ゴリラゴリラ";
gorilla.move(20);
//=> 'ゴリラゴリラ moved 20m.'

nameプロパティはpublic宣言されているため、インスタンスされた変数(gorilla)からの読み書きが可能になっています。「ゴリラ」から「ゴリラゴリラ」に変更することができます。

protected#

protectedアクセス修飾子は自身のクラスとサブクラスからアクセス可能です。

Animalクラスmoveメソッドのアクセス修飾子をpublicからprotectedに変更しエラーを出してみます。

typescript
class 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'.
typescript
class 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倍速く動くゴリラを作ってみます。

typescript
class 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.'
typescript
class 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にアクセスすることが許されずエラーとなります。

typescript
class 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'.
}
}
typescript
class 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メソッドの多くの使い方としては、自身のクラス内の長いコードを機能別に分ける時に利用します。