
再利用性の高いクラス作成に重要な“アクセス制御”
株式会社ガリレオ
小山博史
2010/1/28
■ ドキュメントだけでは自由にコーディングできる
しかし、メソッドを使うようにドキュメントへ書いておいても、それだけではAppを下記のようにコーディングしてしまう人は必ず出てきてしまいます。UserInfoManagerのuserInfoArrayフィールドは、特にアクセス制御されていないため、Appが直接アクセスして操作できてしまうからです。ドキュメントで説明をするだけでは、不十分なのです。
sample14/app3a/App.java(sample14.app3a.UserInfoManager実装依存版)package sample14.app3a;
class App {
public static void main(String[] args) {
UserInfo u = new UserInfo();
u.name = "taro";
u.eMail = u.name + "@example.jp";
UserInfoManager manager = new UserInfoManager();
manager.userInfoArray[0] = u;
System.out.println(manager.userInfoArray[0].name);
System.out.println(manager.userInfoArray[0].eMail);
}
}
このように、ほかのクラスからアクセスできるようにコーディングされてしまうと、あるクラス内のデータ構造を変更することが必要になったときに、影響が出てしまいます。これを防ぐ仕組みとして、Javaでは「public」「protected」「private」といったキーワードが用意されています。
Javaのアクセス修飾子は、3種類
public、protected、privateは、クラス宣言、インターフェイス宣言、メンバ(フィールド、メソッド)宣言時に指定できます。これらを使うことにより、ほかのクラスやオブジェクトからフィールドにアクセスできるようにしたり、制限したり、といったことができます。
- public
publicキーワード付きのメンバは、メンバが定義されているクラスにアクセスできるクラスからアクセス可能 - protected
protectedキーワード付きのメンバは、そのクラスとサブクラスからアクセス可能。また、同じパッケージにあるクラスからもアクセス可能 - private
privateキーワード付きのメンバは、そのクラスからのみアクセス可能 - アクセス修飾子なし
public、protected、privateのいずれも付けていないメンバは、そのクラスと同じパッケージにあるクラスからのみアクセス可能
クラス自身にも、アクセス修飾子を付けられます。クラスの場合は、publicを付けるか、付けないか、といった選択が基本です。publicを付けたクラスは、ほかのクラスからアクセスできます。
また、このクラスから生成されたオブジェクトについても、同様にアクセスできます。付いていない場合は、同じパッケージにあるクラス以外のクラスからはアクセスができなくなります。
コラム 「Javaには“ネストされたクラス”ってのもあります」 |
| クラス自身に付けるアクセス修飾子について補足しておきます。まだ説明していませんが、「ネストされたクラス」というものがJavaにはあります。「ネストされたクラス」では、protected、privateを付けることもできます。ネストされたクラスについては、別途紹介する予定です。 |
アクセス修飾子でクラス依存を解決するには
アクセス修飾子がどういうものか知ったところで、「UserInfoManagerクラスの問題を解決するには、どうすればいいのか」を考えてみましょう。
このクラスは同一パッケージに含まれないクラスからも利用できるように、publicとします。userInfoArrayフィールドへほかのクラスが直接アクセスできないようにするためには、privateを使います。すべてのメソッドは、ほかのクラスから利用可能にするため、publicを付けることにします。
まとめたのが、次のコードです。
sample14/app4/UserInfoManager.javapackage sample14.app4;
public class UserInfoManager {
private java.util.List userInfoArray = new java.util.ArrayList();
public void add(UserInfo userInfo) {
userInfoArray.add(userInfo);
}
public UserInfo get(int id) {
return (UserInfo)userInfoArray.get(id);
}
public String getUserName(int id) {
return get(id).name;
}
public String getUserEmail(int id) {
return get(id).eMail;
}
}
次のようなクラスを作り、コメント部を有効にすると、エラーになりアクセス制御がきちんとできていることが分かります。privateなフィールドへは、ほかのクラスからはアクセスができません。
また、アクセス修飾子指定がないクラスは、ほかのパッケージのクラスからはアクセスできません。
sample14/app4/App.javapackage sample14.app4;
class App {
public static void main(String[] args) {
UserInfo u = new UserInfo();
u.name = "taro";
u.eMail = u.name + "@example.jp";
UserInfoManager manager = new UserInfoManager();
manager.add(u);
System.out.println(manager.getUserName(0));
System.out.println(manager.getUserEmail(0));
// privateなフィールドへはアクセスできない
//manager.userInfoArray.add(u);
//System.out.println(manager.userInfoArray.get(0).name);
//System.out.println(manager.userInfoArray.get(0).eMail);
// アクセス修飾子指定がないクラスへはアクセスできない
//sample14.app1.UserInfo u1 = new sample14.app1.UserInfo();
}
}
ここまでの話で、フィールドをprivateにしておけば、クラス内のデータ構造を変更するような大きな実装変更があっても、ほかのプログラムへの影響を限定的にできることが理解できたでしょうか。
今回までの連載では、publicはおまじないとして付けてもらうことがありましたが、今後は正しく意味を理解して使うようにしましょう。
アクセサメソッド「getter」「setter」とは
フィールドは基本的にprivateとして非公開にするのが安全ですが、ほかのクラスがフィールド値を操作できた方が便利な場合もあります。その場合は、直接フィールドにアクセスさせるのではなく、専用メソッドを用意します。これは、「アクセサメソッド(accessor method)」と呼ばれます。
■ Eclipseだとアクセサメソッド作成が簡単
Eclipseでは、アクセサメソッドを簡単に用意できるようになっています。アクセサメソッドは、フィールドの値をgetしたりsetしたりするために使うものなので、「getter」「setter」と呼ばれることもあり、メソッド名は「get」「set」で始まります。
ただし、フィールドの型がbooleanの場合は、getに対応するメソッド名が「is」で始まります。
UserInfoについて、アクセサメソッドを作成してみましょう。まず、次のクラスを作成します。
sample14/app5/UserInfo.javapackage sample14.app5;
public class UserInfo {
private String name;
private String eMail;
private boolean member;
}
Eclipseでは、下記の手順でアクセサメソッドを簡単に作成できます。
- sample14.app5パッケージのUserInfo.javaをマウスで指定
- 右ボタンをクリックしてメニューを表示
- [ソース]→[GetterおよびSetterの生成]をクリック(図1)
- [GetterおよびSetterの生成]ダイアログで、フィールド「name」「eMail」「member」について、チェックボックスをチェック(図2)
- [OK]をクリック
![]() |
| 図1 クラスを選んで右クリックでメニューを出す |
![]() |
| 図2 [GetterおよびSetterの生成]ダイアログ |
次ページでは、生成されたアクセサメソッドがソースコードではどうなっているのかを確認し、最後にprotected宣言について、解説します。
| Index | ||||||||
|
||||||||
【改訂版】Eclipseではじめるプログラミング バックナンバー 連載インデックスへ»
- 第1回 Eclipse 3.4で超簡単Javaプログラミング基礎入門
- 第2回 Javaで一から理解するプログラムの変数と演算子
- 第3回 プログラミングの醍醐味! Javaで“条件式”を理解する
- 第4回 プログラミングの真骨頂! Javaで“反復処理”を覚える
- 第5回 データ集合を扱うのに便利なJavaの配列と拡張for文
- 第6回 複雑なデータを表現できるクラスやフィールドって?
- 第7回 クラスの振る舞いを表すJavaの“メソッド”とは?
- 第8回 Javaの参照型を文字列操作で理解して文法を総復習
- 第9回 プログラムを「変更」しやすくする“インターフェイス”
- 第10回 Javaの実案件に必須のパッケージとインポートを知る
- 第11回 「static」でクラス共有の変数・メソッドを使いこなせ!
- 第12回 継承やオーバーライドで簡単にクラスを“拡張”しよう
- 第13回 “コンストラクタ”と初期化、本当に理解できてる?
- 第14回 再利用性の高いクラス作成に重要な“アクセス制御”
- 第15回 Javaは「抽象クラス」で実装を上手に再利用できる
- 第16回 “ネスト”した型で始める軽量Javaプログラミング!?
- 第17回 あなたの知らない、4つのマニアックなJava文法
- 第18回 強く型付けされているJavaの理解に必修の“型変換”
- 第19回 キュー構造をJavaで実装してジェネリック型を理解する
- 第20回 拡張for文の真の実力を知り、反復処理を使いこなせ
- 第21回 7ステップで理解するJavaでの列挙型/enum使用法
- 第22回 いまさら聞けない「Javadoc」と「アノテーション」入門
- 第23回 プログラマの宿命! 例外とエラー処理を理解する
- 第24回 Javaの例外処理で知らないと損する7つのテクニック
| Java Solution全記事一覧 |
TechTargetジャパン
- Scalaのパッケージ、アクセス修飾子、オブジェクト継承 (2012/5/22)
インポート、パッケージオブジェクト、抽象クラス/抽象メソッド、オーバーライド、final、シールドクラスなども - 基幹系システムでCloud SQLは使えるか試してみた (2012/5/17)
サンプルとしてMRPシステムを作成して動かし、「再帰呼び出し」などのパフォーマンスを測定して検証してみます - アジャイル管理ツール9選+Pivotal Tracker入門 (2012/5/14)
群雄割拠のアジャイルプロジェクト管理ツールを9つ紹介し、特に注目を集めているPivotal Trackerの基本的な使い方を解説します - サーバサイドJSやJavaでWebアプリが作れるXPages (2012/5/11)
Notes/Dominoの資産をサーバサイドJavaScriptやJavaで操作し、HTMLやJavaScript、CSSをUIにできる技術を紹介
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -


![図2 [GetterおよびSetterの生成]ダイアログ](02.jpg)