カプセル化とは
クラス内のフィールドをprivateで宣言することで外部から値を参照したり、変更したりすることができないようにする。
カプセル化をすると何がいいのか?
カプセル化をすると、外部から値を変更したり、参照したりできなくなるため、宣言しているフィールドに設定される値は、必ず自分自身のクラスで設定することになります。そのため、そのフィールドにどういった値が設定されるかを、そのクラス1つを読むだけで理解できるようになります。
また、フィールドの値の妥当性をチェックする必要がある場合等に、外部からの設定を許可してしまうと、チェックされていない値が設定される可能性があるため、カプセル化により、そういった、不正な値が設定されることを、事前に防ぐことができます。
例えばint項目に1から100までの値しか設定させたくない場合、このフィールドをpublicで公開してしまうと、外部のクラスが勝手に200と設定する可能性もあります。外部のクラスも1から100のチェックをしてから設定してくれれば、そういった不具合は防ぐことが可能ですが、すべての開発者がそういった思想でプログラミングを行うのは大変なことで、間違いを誘発してしまいます。それであれば、最初から設定できないようにしておくことで、そういったミスがなくなります。
じゃあどうやって値を設定するの?
カプセル化をしてしまうと、外部からの値の変更ができなくなります。そうしてしまうとミスはなくなりますが、設定したい値を設定できなくなり、クラスとして機能しなくなります。よって、何らかの方法で、外部からの値の変更を可能にする必要があります。
カプセル化されているフィールドの値を外部から変更する方法は次の2種類があります。
カプセル化されているフィールドの値を外部から変更する方法1
namespace CS22 { public class ClassA { private int _count = 0; public ClassA(int count) { _count = count; } } }
上記の例では_count変数がprivateのフィールドで宣言されており、カプセル化されている状態です。この値を変更するためにコンストラクタでintの値を指定されることで、_countの初期値を設定することができます。
カプセル化されているフィールドの値を外部から変更する方法2
値を設定するメソッドを公開する。
コンストラクタで設定する方法は、クラスを生成するときにしか動作しないため、初期値しか指定することができません。生成後に値を変更したくても、コンストラクタだけでは対応できません。そこで、値を変更することのできるメソッドを公開するやり方があります。
namespace CS22 { public class ClassA { private int _count = 0; public ClassA(int count) { _count = count; } public void Call() { _count++; } public void SetCount(int count) { //ここで自由にチェックができる、統一する。 _count = count; } public int GetCount() { //ここで事前処理をすることもできる return _count; } } }
SetCountメソッドで引数に値を指定させて、_countの値を変更できるようにしています。このように外部から値を変更するメソッドを公開するのであれば、publicなフィールドを宣言しても同じのように感じるかもしれませんが、一つ決定的な違いがあります。
それは、「処理を書けるかどうか」です。
フィールドの場合は値を設定することしかできないので、チェック処理等を書きたくても書くことができません。しかし、メソッドとして公開されている場合は、チェック処理等を書くことができます。という事は、_count変数の値を変更する場合に、チェックするべきことがあるなら、必ずチェックしてから、値を変更するというプログラミングをすることができます。このようにしておけば、複数の開発者でプログラムを開発しても、すべての人が、共通意識をもってプログラミングをすることができます。
このようにprivateフィールを外部から設定するときは、メソッド経由で値を変更させます。外部から値を取得したい場合も同様にメソッドを作成することで取得します。この場合もメソッドで公開することで、後からでもチェック処理を追加することが可能となります。
代替案
このように、フィールドをprivateにして、メソッドをpublic等で公開することで、カプセル化を実現していますが、C#ではプロパティという機能を使うことで、同様のカプセル化が可能です。
- C#初心者のための基礎!C#文法2割の知識で8割の仕事をする方法!#1
- C#初心者のための基礎!ブロックと名前空間とクラスとメソッドを解説#2
- C#初心者のための基礎!#3値の扱い方。変数と定数をわかりやすく解説!
- C#初心者のための基礎!データ型の種類と使い分けをわかりやすく解説#4
- C#初心者のための基礎!値型と参照型の違いと使い方をわかりやすく解説#5
- C#初心者のための基礎!データ型の変換のやり方をわかりやすく解説#6
- C#初心者のための基礎!配列の使い方をわかりやすく解説#7
- C#初心者のための基礎!動的配列List<T>の使い方をわかりやすく解説#8
- C#初心者のための基礎!演算子の使い方をわかりやすく解説#9
- C#初心者のための基礎!if文とswich文の使い方をわかりやすく解説#10
- C#初心者のための基礎!while文の書き方と使い方をわかりやすく解説#11
- C#初心者のための基礎!do-While文の書き方と使い方をわかりやすく解説#12
- C#初心者のための基礎!for文の書き方と使い方をわかりやすく解説#13
- C#初心者のための基礎!foreach文の書き方と使い方をわかりやすく解説#14
- C#初心者のための基礎!オブジェクト指向の意味をわかりやすく解説#15
- C#初心者のための基礎!クラスの意味と使い方をわかりやすく解説#16
- C#初心者のための基礎!コンストラクタの意味と使い方をわかりやすく解説#17
- C#初心者のための基礎!アクセス修飾子の意味と使い方をわかりやすく解説#18
- C#初心者のための基礎!メソッドの意味と使い方をわかりやすく解説#19
- C#初心者のための基礎!フィールドの意味と使い方をわかりやすく解説#20
- C#初心者のための基礎!インスタンスの意味と使い方をわかりやすく解説#21
- C#初心者のための基礎!カプセル化の意味と使い方をわかりやすく解説#22
- C#初心者のための基礎!プロパティの意味と使い方をわかりやすく解説#23
- C#初心者のための基礎!Disposeとusingの意味と使い方を解説#24
- C#初心者のための基礎!staticスタティックの意味と使い方を解説#25
- C#初心者のための基礎!継承の意味と使い方をわかりやすく解説#26
- C#初心者のための基礎!override(オーバーライド)の使い方を解説#27
- C#初心者のための基礎!ポリモーフィズムとインタフェースの使い方を解説#28
- C#初心者のための基礎!ポリモーフィズムと抽象クラスの使い方を解説#29
- C#初心者のための基礎!例外Exceptionの意味と使い方をわかりやすく解説#30