この機能を使って生成されたアクセサメソッドを持つクラスは、下記のようになります。
package sample14.app5; class UserInfo { private String name; private String eMail; private boolean member; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEMail() { return eMail; } public void setEMail(String mail) { eMail = mail; } public boolean isMember() { return member; } public void setMember(boolean member) { this.member = member; } }
Javaでは、「JavaBeansコンポーネントアーキテクチャ」といわれるものがあり、このコンポーネントアーキテクチャを採用している環境では、オブジェクトの属性はアクセサメソッドで表現します。
UserInfoクラスは、属性name、email、memberが定義されていて、属性nameの値はgetNameメソッドで取得できますし、setNameメソッドで設定できるということです。
最後に、protected宣言されたフィールドを持つクラスも作成してみましょう。次のように、protectedなString型のフィールド「f1」を持つSampleクラスを作成してみます。
package sample14.app6; public class Sample { protected String f1; private String f2; }
Sampleクラスを拡張するSample1クラスを次のように作成します。f1についてはprotectedなので、Sample1クラスで利用できることが分かります。しかし、private宣言されたフィールドf2はSample1クラスでは利用できません。すなわち、コメント部分を有効にすると、エラーになります。
package sample14.app6; public class Sample1 extends Sample { public void setF1(String f1) { this.f1 = f1; } public String getF1() { return f1; } /* f2はprivateフィールドなので使えません public void setF2(String f2) { this.f2 = f2; } public String getF2() { return f2; } */ }
SampleクラスとSample1クラスを利用するAppクラスを次のように作成します。f1についてはprotectedなので、同一パッケージであるAppクラスで利用できることが分かります。しかし、private宣言されたフィールド「f2」はAppクラスから利用できません。
なお、Sample1がSampleから実装継承したフィールド「f1」についても、同じアクセス制限が適用されるため、Appからアクセスできます。
package sample14.app6; public class App { public static void main(String[] args) { Sample sample = new Sample(); sample.f1 = "f1"; System.out.println(sample.f1); // sample.f2 = "f2"; // privateなフィールドは使えない Sample1 sample1 = new Sample1(); sample1.f1 = "f1"; System.out.println(sample1.getF1()); } }
packageが別になると、protectedなフィールドであるf2も使えなくなるので、sample14.app7.Appクラスでは、sample14.app6.Sampleクラスのf1へは直接アクセスできません。しかし、sample14.app7.Sample1のsample14.app6.Sampleを拡張した場合は、f1へアクセス可能です。
package sample14.app7; import sample14.app6.Sample; public class Sample1 extends Sample { public void setF1(String f1) { this.f1 = f1; } public String getF1() { return f1; } }
package sample14.app7; public class App { public static void main(String[] args) { sample14.app6.Sample sample = new sample14.app6.Sample(); // sample.f1 = "f1"; // ほかのパッケージ内クラスのprotectedなフィールドは使えない Sample1 sample1 = new Sample1(); System.out.println(sample1.getF1()); } }
今回は、アクセス制御について説明しました。あるクラス内のデータ構造にほかのクラスが依存してしまうと、そのデータ構造を変更するときに大きな影響があることから、ほかのクラスが使用する必要がないフィールドやメソッドについては、アクセスできないようにすることは理解できたでしょうか。
ほかのクラスに使用してもらうフィールドやメソッドについては、publicキーワードを付け、自分のクラスでしか使用しないフィールドやメソッドについては、privateキーワードを付けるという基本を身に付けてください。アクセス制御のためのキーワードを付けたり、protectedキーワードを付けたりするクラスを設計することは、初心者のうちはあまりないかもしれませんが、文法的な意味はきちんと理解して、使えるようにしておきましょう。
今回作ったサンプルのソースコードはこちらからダウンロードできます。
小山博史(こやま ひろし)
情報家電、コンピュータと教育の研究に従事する傍ら、オープンソースソフトウェア、Java技術の普及のための活動を行っている。長野県の地域コミュニティである、SSS(G)やbugs(J)の活動へも参加している。
著書に「基礎Java」(インプレス)、共著に「Javaコレクションフレームワーク」(ソフトバンククリエイティブ)、そのほかに雑誌執筆多数。
Copyright © ITmedia, Inc. All Rights Reserved.