アクセス修飾子
このレッスンでは、public・protected・修飾子なし・private の4段階の可視性を判定できるようになります。
まず予測してください
class Account {
public String pub = "public";
protected String pro = "protected";
String pkg = "package"; // 修飾子が無い
private String pri = "private";
}同じファイルにある別のクラスから、この4つのうちいくつ触れるでしょうか。答えは3つです。触れないのは pri だけです。
4段階の広さ
private を最も狭いほうとして、広がっていく順に並べます。
| 修飾子 | 同じクラス | 同じパッケージ | 別パッケージの子クラス | どこからでも |
|---|---|---|---|---|
private | 可 | 不可 | 不可 | 不可 |
| 修飾子なし | 可 | 可 | 不可 | 不可 |
protected | 可 | 可 | 可 | 不可 |
public | 可 | 可 | 可 | 可 |
試験でいちばん狙われるのが、上から2番目の修飾子なしです。パッケージプライベート、あるいはデフォルトアクセスと呼ばれます。書き忘れたのではなく「同じパッケージにだけ見せる」という意思表示なので、選択肢に default というキーワードが出てきたら注意してください。アクセス修飾子としての default は存在しません。default はインターフェースのメソッドに付ける別の予約語です。
protected の勘違い
protected は「子クラスからだけ見える」と誤解されがちですが、実際には同じパッケージからも見えます。子クラスかどうかに関係なく、同じパッケージのクラスなら触れます。
さらに細かい規則として、別パッケージの子クラスから protected メンバに触るときは、自分自身か自分の型のインスタンスを通してのみ触れます。親型の変数を経由して触ることはできません。ここは第6章の継承で改めて扱います。
クラス自体に付けられるのは2つだけ
トップレベルのクラス、つまりファイル直下に書くクラスに付けられるのは public と修飾子なしの2つだけです。private class Foo や protected class Foo はコンパイルエラーになります。
また、1つのファイルに public なトップレベルクラスは1つまでで、その名前はファイル名と一致していなければなりません。逆に修飾子なしのクラスなら、同じファイルにいくつ書いても構いません。この性質を使うと、1ファイルの中で「同じパッケージの別クラス」からのアクセスを試せます。
演習で確かめます
1つのファイルの中に Main と Account を並べ、4種類のフィールドのうちどこまで触れるかを実際に確かめます。
要件
- Account に、private フィールド pri を返す reveal メソッドを追加すること
- access は Account を1つ作り、pub, pro, pkg, reveal() の順で sep を挟んでつなぐこと
- Account のフィールドの修飾子は書き換えないこと
- Main から a.pri を直接書かないこと
入出力例
access("-") → "public-protected-package-private"
access("/") → "public/protected/package/private"
access(" ") → "public protected package private"