第12回 クラスの利用TypeScriptで学ぶJavaScript入門(5/6 ページ)

» 2015年07月16日 05時00分 公開
[羽山博]

情報の隠蔽

 ここまでのCatクラスには、まだまだ不十分な点がある。例えば、heightプロパティやweightプロパティにはおよそ猫らしくない体長や体重の値を設定できるし、nameプロパティにはとてつもなく長い名前を設定できる。実際、体長が100メートルの猫とか、体重が1トンの猫というのは、生物学的な猫としては考えられない値なので、そのような値を設定しようとしたときにはエラーにするという対応が必要になってくる。また、長い名前でもできるだけ許容するというのが本来あるべきシステムなのかもしれないが、現実には何文字かに制限したいこともあるだろう。

 話を簡単にするために、ここでは名前を8文字に制限することにしよう。そのためには、nameプロパティをクラス外から自由にアクセスできないようにして、長さのチェック機能を持ったメソッドを使ってのみアクセスできるようにすればよい。

 図で表せば、以下のようなイメージになる。プライベート(private)なメンバー(ここではnameプロパティ)はクラス外からはアクセスできないが、パブリック(public)なメンバー(ここではsetName/getNameメソッド)はクラスの外からでもアクセスできるので、パブリックなメソッドを使ってのみアクセスできるようにして、setNameメソッドで名前が8文字以内かをチェックするというわけだ。

図8 情報の隠蔽のイメージ 図8 情報の隠蔽のイメージ
nameプロパティをprivateにして、クラスの外からアクセスできないようにするとともに、setName/getNameという二つのpublicなメソッドを使って値の設定や取得ができるようにした。

 この例では、nameプロパティには直接アクセスできないが、setNameメソッドやgetNameメソッドを使えばアクセスできるようになる。このようにすれば、nameプロパティに値を設定するに当たって、不正な値が設定されないかどうか、setNameメソッドで事前にチェックできる。また、getNameメソッドで表示形式の変更などの処理をしてからnameプロパティの値を返せる。

 このように、重要な情報をプライベートな変数にして、クラスの外から勝手に変更されないようにすることを「情報の隠蔽」と呼ぶ

 では、コードを書いてみよう。コードを見やすくするために、コンストラクターや他のプロパティに関連する箇所は省略する。

class Cat {
  private name: string// (1)
  public setName(s: string) {  // (2)
    this.name = s.slice(0, 8);  // (3)
  }
  public getName(): string// (4)
    return this.name;
  }
}

var myCat = new Cat();
myCat.setName("じゅげむじゅげむごこうのすりきれねこ");  // (5)
alert("私の猫の名前は" + myCat.getName() + "です");  // (6)
window.close();


 (1)では、nameプロパティの宣言の前に「private」というキーワードを指定している。これで、クラス外からはアクセスできない変数となる。(2)はnameプロパティの値を設定するためのメソッドである。このメソッドにはsという名前の仮引数が一つあり、そのデータ型はstringとなっている。仮引数sに渡された文字列は、(3)のsliceメソッド(これはstringクラスのメソッド)により0文字目から8文字目の手前までが切り出され、nameプロパティに代入される。sliceメソッドは引数に指定した開始位置から終了位置までの文字列を返すが、文字列の先頭を0文字目と数えることと、終了位置に指定した値の手前の文字までを返すことに注意しよう。

 (4)はnameプロパティの値をそのまま返すメソッドとなっている。こちらの方は特にデータの加工などはしていない。

 このようなメソッドを書いておけば、(5)のようにsetNameメソッドを使ってnameプロパティに値を設定できる。ただし、長い文字列を指定しても、最初の8文字だけが使われることになる。また(6)のようにgetNameメソッドを使って値を取り出せる。

図9 nameプロパティに設定される文字列を8文字までに制限したプログラムの実行例 図9 nameプロパティに設定される文字列を8文字までに制限したプログラムの実行例
setNameメソッドの引数に指定した文字列は18文字だが、先頭から8文字が有効とされた。

 このようにして情報を隠蔽した場合、(5)(6)の部分のコードを以下のように書くとエラーになる。nameプロパティにアクセスするには、必ずsetNameメソッドとgetNameメソッドを使う必要がある、というわけだ。

myCat.name = "じゅげむじゅげむごこうのすりきれねこ";
alert("私の猫の名前は" + myCat.name + "です");

プライベートな変数を直接使うとエラーになる(TypeScript)
nameプロパティがprivateを指定して宣言されている場合は、このようにして直接アクセスしようとするとエラーになる。

 日常の例でいえば、住民データの取り扱いなどに似ている。役所に保管されている住民データは、当然のことながら、好きなように見たり、書き換えたりできるようにはなっていない。つまりそれらのデータはプライベートなデータということになる。しかし、窓口で一定の手続きを取れば、閲覧したり、修正したりできる。この手続きは誰にでも公開されているパブリックなメソッドということになる。

 なお、変数の宣言やメソッドの定義の前に何も書かなかった場合には、publicが指定されたものと見なされることにも注意しよう。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。