これまではオブジェクト指向の使い方の話とか、
クラスと型の違いとか概念的な話が多かったです。
今度はまたオブジェクト指向プログラミングの基本的な使い方の話に戻って、
privateとpublicという修飾子について説明していきます。
privateとpublicの基本的な使い方
privateとpublicはJavascriptでは使えないのでこれまで書きませんでしたが、
C#やJavaといった主要なオブジェクト指向プログラミング言語では必ず使います。
privateとpublicはアクセス修飾子といって、
以下のようにクラスやプロパティやメソッドにつけていくものです。
public class Car() { private int property1; public int property2; private void methodSample1() { **(処理)** } public void methodSample2() { **(処理)** } }
そして、privateをつけたものは宣言した場所でしか使えず、
publicをつけたものはどこからでも参照して使うことができます。
これがアクセス修飾子の基本ルールです。
C#やJavaやVisual Basicいったオブジェクト指向言語だと、
これが積極的に使われています。
図示すると以下のようになります。
このように、参照可能な範囲のことをスコープと良います。
C言語のように古典的な言語の場合は、
「変数はただの箱みたいなものだし、どこからでも出し入れ可能で良し」
「関数の処理もどこからでも呼べて良し」
という思想でした。
Javascriptもプロトタイプベースのオブジェクト指向ということで、
オブジェクト指向に関しての仕様がユルく、アクセス修飾子の概念がありません。
なので、宣言したものはどこからでもアクセス可能で、
全部publicになっています。
しかし、より大きなソフトウェアを扱うほどそれだと問題が出てくるようになったので、
参照可能な範囲が設定できた方が良い、ということで、
privateとpublicが導入されるようになったわけです。
様々なプログラミング言語におけるprivateとpublic
アクセス修飾子はprivateとpublicの二つが基本ですが、
他にもprotectedというものがあったり、「何もつけない」というケースがあったりします。
C#とJavaとVisual Basicの場合、それぞれ以下のルールになっています。
C#
public | どこからでもアクセス可 |
private | 宣言したクラス内からのみアクセス可 |
何もつけない | privateと同様 |
protected | 宣言したクラス内と、クラスの継承によって派生したクラス内からのみアクセス可 |
internal | 同じプロジェクト内ならどこからでもアクセス可 |
Java
public | どこからでもアクセス可 |
private | 宣言したクラス内からのみアクセス可 |
何もつけない | 同じパッケージ内ならどこからでもアクセス可 |
protected | 宣言したクラス内と、クラスの継承によって派生したクラス内からのみアクセス可 |
Visual Basic
Public | どこからでもアクセス可 |
Private | 宣言したクラス内からのみアクセス可 |
何もつけない | Publicと同様 |
Protected | どこからでもアクセス可 |
Friend | 同じプロジェクト内ならどこからでもアクセス可 |
以上。大体どれも似ていますが、
何もつけない場合の処理が違うことに注意?といった所でしょう。
ただ、基本的に特別な意図がない限りはprivateかpublicを書いておくことが推奨されます。
あと、C#にはinternalというものがあり、VisualBasicにはFriendというものがありますが、
これはどの道、参照範囲が広いのでpublicと似たようなものです。
そこまでよく使うものではないので、とりあえずはあまり意識しなくて良いと思います。
それから、protectedはクラスの「継承」を使う場合に意識するべきものです。
継承については後ほどやります。
「継承」や「protected」まで使っていくのは、
初級のレベルは逸脱しているし、高度な設計をちゃんとしていく話までいかないとそこまでは考えないです。
これについては次回にやる「クラスの継承について」と同様に学んでいきましょう。
なので、とりあえず初めのうちはprivateとpublicだけ意識しておくと良いと思います。
ちなみに、極論を言うと全部publicにしとけば、とりあえず動くものは作れます。
(そんなことをしたのを先輩に見られたら、恐らく「なんて駄目なプログラマなんだ」と思われるでしょうが・・・)
とりあえずpublicだけでも動くものが作れるものの、
後述する「カプセル化」の考え方が重要なので、
privateが積極的に使われるものです。
「カプセル化」という発想
オブジェクト指向プログラミングで重要な発想の一つに「カプセル化」というものがあります。
カプセル化は「カプセルのように他から容易にアクセスできないようにすること」です。
それから、「隠蔽する」という意味もあります。
まず、クラスを作ったりメソッドを作ったりすることは、
処理の「部品」を作ることと同義です。
それに加えてカプセル化が行われた場合、
その部品は不用意にアクセスできず、アクセス不要のハードボックスみたいな領域になります。
車で例えると、「エンジン」に関する処理を「カプセル化」するとして、
「エンジンを動作する」という処理や、
「エンジンのパワー」といったプロパティがあるとしましょう。
そんでもって、「エンジンの起動は車にキーを入れた時だけで、他は必要ない!」みたいに、
「この動作は特定の処理から呼ぶようにしないと困る」とか、
「どこからでも値を変えることができてしまったら処理に不都合が出る」といったことがある場合、
「カプセル化」の発想が必要になります。
要は、外からどこでも呼んで欲しくないメソッドをprivateにしたり、
外から変えて欲しくないプロパティをprivateにしたりして、
一部の処理を限定的にすることで、全体の処理を円滑にすることがカプセル化の意義です。
カプセル化は突き詰めると難しい話で、
やればやるほど自由度が無くなるので、ぎこちなくなってくる問題もあります。
とある処理をprivateにしてみたが、
後にpublicにしといた方が良かった…ということもあるかもしれません。
この辺は正解が難しい話だと思います。
あと、privateを積極的に使う理由には
「ソースコードの読みやすさを考慮して」というのがあります。
極論を言うと全部publicにしとけば、とりあえず動くものは作れますが、
privateと宣言しておくと「この処理はこのクラスでしか使えないことを想定している」
といったことが見てすぐ分かるようになります。
中小規模ぐらいのシステムだと、あまり高度なことまで考えなくても良いかもしれないので、
privateと宣言されているものは「このメソッドはこのクラスでしか使わないことを示す」ものとして使うことが多いでしょう。
以上の意図を踏まえて、privateとpublicを使い分けていきましょう。
これもまた、オブジェクト指向プログラミングの基本になります。
- 「private」や「public」はアクセス修飾子といって、プロパティやメソッドにつける
- privateをつけたものは宣言した場所でしか使えず、
publicをつけたものはどこからでも参照して使うことができる、が基本 - 参照可能な範囲のことをスコープと言う
- アクセス修飾子の仕様は各言語によって微妙に違うので要確認
- 修飾子「protected」はクラスの継承と一緒に学んでいこう
- 全部publicにすれば動くものは作れるし、Javascriptは全部publicになる
- メソッドやプロパティを他から容易にアクセスできないようにする
「カプセル化」という考え方がオブジェクト指向言語において重要
コメント