私のイメージでは
カプセル化=データの隠蔽化
=変数のprivate化
=セッター、ゲッターによる変数の使用
なのですが、イマイチデータの隠蔽化になっていない気がしてしてならないです。
そもそもprivate化してもgetterで取得することが出来て、しかもsetterで
データを書き換えることが出来るので、隠蔽化できていない気がするのですが、
実際はどう違うのでしょうか
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
クラス内のフィールド変数に対して、何も考えずにgetterとsetterを付けることは間違いで、それはもはやオブジェクト指向ではありません。
ある変数にはgetterを定義し、setterは定義しないとすると変数は読み取り専用になる。
カプセル化とは適切なアクセス制限を行い最低限の情報を公開する設計方針です。
投稿2017/06/02 09:06
編集2017/06/02 09:06総合スコア18155
0
カプセル化は、堅牢なクラス設計のための考え方です。隠蔽化はそのメリットの一つにすぎません。
例えば、Car、Engineというクラスがあって、CarはEngine engine = new Engine();のフィールドを持っていたとします。
まず、もしengineがpublicならば、外部からengineを好きなように操作できて、500km/hのような無茶苦茶なスピードを出したりもできます。
そこで、engineをprivateにして、加速はspeedup()(=セッター)をいうメソッドで行うようにします。
このメリットは二つあって、一つはspeedup()の実装内で速度制限を設けるなどして、外部から無茶苦茶な速度にできなくなります。
もう一つは、もしEngineクラスの実装が複雑であっても、Carのユーザはspeedup()というAPIだけを知っていれば良いということです。車を運転する人で、エンジンの仕組みを熟知している人はいませんよね。アクセルの操作のみで車を加速できるはずです。
このように、フィールドをprivateにしてアクセサメソッドを設ける実装にすれば良いクラスを設計できるというのが、カプセル化の考え方です。
投稿2017/06/02 09:20
編集2017/06/02 09:22総合スコア234
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
カプセル化は、"オブジェクトに対する操作は全てメソッドによって行う"と制限することによって、オブジェクトの内部を見せなくする(ある種の抽象化がされる)事です。
外部から値を設定したり、値を参照したりする必要がある変数については、セッターやゲッターを設けますが、そうしたメソッドを設けるか否かはクラスの設計思想によって決まります。
Private変数のすべてに無節操にセッターとゲッターを設けるのは、カプセル化の概念を理解していない方だと思います。
投稿2017/06/02 08:59
総合スコア6915
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは。
詳しい解説や定義は他の人が回答しているので、根本的な概念を簡単に表現します。
オブジェクトの変数をpublicにすると、他の誰もが値を自由に変更することが出来る。言い換えると、状態を変更する「責任」がその値を変更する側に分散する。getter/setterを介してprivate変数を操作する設計にすると、状態を変更する「責任」は、そのオブジェクト自身が持つことになる。こうやって、オブジェクトの状態を管理する「責任」をそれぞれのオブジェクトに閉じ込めること、これがgetterとsetterの存在意義です。
投稿2017/06/02 11:29
総合スコア4239
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
もちろん例えかある部分から見て。ですよ。
完全にカプセル化 ( ブラックボックス化 ) だと 編集 ( オブジェクト自身の ) すら不可能。
カプセル化というのは、外部クラスやメソッド ( C/C++だと グローバル関数とかも含む。 ) からは見えない。
という意味。
確かにget/setを設けるとほとんどグローバル変数 ( Javaだと static な public変数か、public変数みたいなもの。 ) と同等ですが、
にあるように、
条件を設定したり、範囲を限定することができます。
たとえば、getはありだけど、setは無し とすると
閲覧は可能だけど、書き換え不可。
とか。
投稿2017/06/02 10:52
総合スコア4962
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
私なりの
#「カプセル化」と「隠蔽化」の違い
以下の信号機を表すクラスがあるとします。
public class 信号 { public Color 現在の色 }
一番上は、色がpublicになっている&アクセスメソッドのない
外部から自由に色を変更できるキケンなクラスです。
public class 信号 { private Color 現在の色 public void setColor(Color color) public Color getColor() }
現在の色を隠蔽化しましたが、色を自由に設定できるためあまり効果がありません。
※ここが質問の発端ですね。
setColorで、青黄赤以外の色場合、エラーにする実装も可能ですが、
例外を発生させるくらいなら、次のようにしたほうがよいです。
public class 信号 { private Color 現在の色 public void setGreen() public void setYellow() public void setRed() public Color getColor() }
全てのメソッドから引数がなくなったため、かなり使いやすくなり。
想定外の色が設定できないようになりましたが、これでも問題があります。
でも、信号の色が
青 => 黄 => 青 のように、現実でありえない色が設定できてしまうことです。
これも入力チェックのようなもので解決できますが、イマイチです。
public class 信号 { private Color 現在の色 public void changeColor() public Color getColor() public boolean canGetOn() // 進めるか }
色を気にせずに変更することが可能になりました。
また、信号機で重要なのは色でなく「進めるか?」というのを考えて
canGetOn というメソッドを用意しました。
このように内部の仕様などを意識せずにクラスを使える(changeColor)ようにするのが
「カプセル化」だと考えています。
「カプセル化 = データ + 手続き + 外部インターフェース」
と、いっています。
データ:現在の色
手続き:changeColorの実装
外部インターフェース:chageColor、getColor、canGetOn
という感じです。
長文失礼しました。
投稿2017/06/02 10:07
編集2021/01/08 01:34総合スコア4826
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。