みなさまこんにちは。
Numataです。
今回は不可視をやっつけましょう。
Java学習ではほとんどEclipseが使われます。
Eclipseを使っていると99%の方が見たことあるエラーがこちらです。
1 |
フィールド は不可視です。 |
私も初めてこのエラーに出会ったときは、
「不可視ってなんやねん!見せろや!!」
と思いました(笑)
このエラーの原因は、オブジェクト指向のメイン機能の一つである
カプセル化が働いているためです。
正しくカプセル化を理解して、不可視をやっつけましょう!!
もくじ
全てのフィールド・メソッドにはアクセス修飾子がついています
今まで何の疑いもなく何度も見てきたであろう
public static void main(String args[])
これにもアクセス修飾子 public がついています。
今まで何の疑いもなく何度も見てきたであろう
String name;
これにもアクセス修飾子 デフォルト(何もつけない) が設定されています。
このようにすべてのフィールド・メソッド(クラスも合わせてメンバといいます)
には、アクセス修飾子といわれる、
公開範囲を設定する語句
がついています。
これがカプセル化という機能のルールになっています。
つまりJavaのルールということですね。
Javaにあるたくさんの機能の中にカプセル化というものがあり、
そのカプセル化機能のルールとして、
全てのメンバにアクセス修飾子を設定する
というものがあるわけです。
これまでの学習で全く意識してこなかったと思います。
そのため、カプセル化の概念になれるまでは、
public や private のような語句に注意が向かず、
見落とすことは本当によくあります。
大丈夫です。
Java学習者が全員通る道です。
とりあえず、
全てのメンバ(クラス・フィールド・メソッド)
にはアクセス修飾子がついている
ということを覚えてください。
この後どのようなルールなのか詳しく説明していきます!
公開する範囲は必ず決めます
なぜでしょうか。
そもそもカプセル化という機能は、
メンバの公開範囲をコントロールするために存在する機能です。
その機能が存在するのに、
公開する範囲が決まっていない
という状態のメンバがあったらおかしな話ですよね。
機能として欠陥のあるものになってしまいます。
公開範囲を設定していないときに
仮に他のクラスから参照された場合、
Javaはそのメンバを公開して良いかの判断ができません。
公開範囲をすべてのメンバに定めることで、
確実な判断基準を設けているのです。
アクセス修飾子には4種類あります
公開範囲を指定する語句をアクセス修飾子といいます。
アクセス修飾子には4種類あり、それぞれ別の公開範囲を持っています。
公開範囲 | アクセス修飾子 | 公開範囲の説明 |
狭 | private | 同クラスのみ |
なし(何も書かない) | 同パッケージのクラスのみ | |
protected | 同パッケージのクラス・継承関係にある子クラスからの参照 | |
広 | public | すべてのクラス |
これはもう覚えるしかないです。
アクセス修飾子の公開範囲は3つの軸で設定されています!
・クラス
・パッケージ
・継承関係
この3軸があることだけは今覚えましょう!!
各修飾子の公開範囲は暗記するまで読み込んで覚えましょう。
1回覚えたらなかなか忘れることはありません。
プログラミングは基本的には理屈を理解しないと応用が利かないので、
理屈を覚えるべきなのですが、
アクセス修飾子に関しては理屈はありません(笑)
気合で暗記しましょう!
この4つの修飾子は必ずすべてのメンバについています。
1点気を付けたいのは、”修飾子を付けない”という修飾子があることです。
表で上から2番目の公開範囲のものです。
ちなみにこれは呼び方がいくつかあります。ここではよく使われる2つ紹介します。
「デフォルト修飾子」
何も書かない=デフォルトのまま から
「パッケージプライベート」
パッケージ内のみの公開範囲=パッケージのprivate から
ちなみに私はデフォルト修飾子と呼んでいます!!
以下プログラムで具体的に見ていきましょう!
1 2 3 4 5 6 7 8 9 |
public class Human { String name; private int birthDay; void aisatsu() { System.out.println(this.name + "です。こんにちは。"); } } |
1 2 3 4 5 6 7 |
public class Sample { public static void main(String[] args) { Human human = new Human(); System.out.println(human.name); System.out.println(human.birthDay); //birthDayは不可視です とエラーがでる } } |
Sampleクラスで、humanインスタンスを作成し、
birthDayフィールドを参照するとコンパイルエラーになってしまいます。
これは、HumanクラスのbirthDayフィールドに private がついていることが原因です。
privateの公開範囲は同クラスのみのため、
他クラスである、Sampleクラスから参照すると、コンパイルエラーになります。
birthDayフィールドのアクセス就職をpublicに変えれば、解決できます!
ちなみにこのプログラムで、クラス・フィールド・メソッド全てに
アクセス修飾子がついていることが確認できます。
このように知識を取り入れた後に意識してみると、
今まで視界に入っていなかったモノが見え、
プログラムの理解度が高まります!
各メンバのアクセス修飾子に注意しましょう
メンバには必ずアクセス修飾子がついています。
public protected デフォルト(何もつけない) private
それぞれの修飾子の公開範囲を忘れても
・クラス
・パッケージ
・継承関係
この3点を軸に見ることだけは忘れないでください!
これでもう不可視に悩まされることもなくなるはずです!
最後までご覧いただきありがとうございました。
コメント
不可視さっぱり分からなかったのでめっちゃ参考になりました。ありがとうございます。
追記:
「birthDayフィールドのアクセス就職をpublicに変えれば、解決できます!」
の「就職」が誤字ってました。