Javaのクラスのアクセス制御と複数クラスの宣言
Javaを基礎から復習していて、クラスについて理解が曖昧だった部分があったのでまとめておきます!
注意して書いているつもりですが、誤りがあればご指摘いただければと思います🙇♂️
クラスに対するアクセス制御レベル
クラスに対するアクセス制御のレベルとしては2つのみです。(⚠️メンバに対しては4つある)
以下にまとめます。
名前 | 指定方法 | アクセス許可の範囲 |
---|---|---|
package private | 何も書かない | 自分と同じパッケージに属するクラス |
public | public | どこからでも |
なので、クラスを宣言するときは、publicをつけるか何もつけないかの2択になります。
クラスだけでなく、列挙型であるenum
を宣言するときも同じです。
private class Hoge
とかやってjavacすると、
修飾子privateをここで使用することはできません
って怒られます。
1つのファイルに複数のクラスを宣言する
1つのファイルに複数のクラスを宣言するとき、大きく分けて2つ方法があります。
- 入れ子構造にせずに宣言する
- 入れ子構造にして宣言する
まず入れ子構造にせずに宣言する方から。
入れ子構造にせずに宣言する
Javaのルールとして、
- 1つのファイルに1つのpublicクラス
- ファイル名 = publicクラス名
があります。
なので、これを守っていれば1つのファイルに複数のクラスを宣言することができます。
いくつか例を見ます。
①
以下のような、public classが1つ、package private class が複数あるHoge.java
はOKです。
public class Hoge {} // public class
class Fuga {} // package private class
class Piyo {} // package private class
②
以下のようなpublic class が1つのファイルに複数あるファイルはNGです。
クラス Fugaはpublicであり、ファイルFuga.javaで宣言する必要があります
とエラーが出ます。
publicなenumとpublicなclassを1つのファイルに同居させるのもNGです。
public class Hoge {} // public class
public class Fuga {} // ⚠️public class2つめ!
class Piyo {} // package private class
③
以下のようなpublic classが1つもなく、package private class が複数あるファイルは…OKです!
しかも、ファイル名は自由に決められます!Hoge.java
でもFuga.java
でもYakiniku.java
でもOKです!
ただこのケースはあまり一般的ではないと思います!!
class Hoge {} // package private class
class Fuga {} // package private class
class Piyo {} // package private class
入れ子構造にして宣言する
入れ子構造にして複数クラスを宣言する方法は3つあります。またクラスの内部に宣言されたクラスのことをインナークラスと呼びます。
なので、インナークラスの種類が3つとも言えます。
- メンバクラス(staticあり、staticなし)
- ローカルクラス
- 匿名クラス
インナークラスはあまり登場頻度が高くないらしいので特徴をちょろっと箇条書きしておくにとどめておきます。
メンバクラスの特徴
- クラスブロックの内部で宣言される
- staticありで宣言した場合
- 外部クラスのstaticなメンバにのみアクセスできる
- 利用するときは、
Outer.Inner oi = new Outer.Inner();
- staticなしで宣言した場合
- 外部クラスのstaticでないメンバにもアクセスできる
- 外部クラスのインスタンスを生成してからでないと利用できない
- 利用するときは
Outer o = new Outer; Outer.Inner i = o.new Inner();
ローカルクラスの特徴
- クラスの中のメソッドの中で宣言される(そのメソッド内でのみ利用可能)
- 利用するときは(宣言されたメソッド内で)
Inner i = new Inner();
匿名クラスの特徴
- 文の中で(式の一部として)宣言(と利用)される
- 利用するときは
Object o = new Object() { ... }
終わり
以上です。
何か誤りがあれば教えていただけると嬉しいです🙇♂️
Discussion
入れ子構造であればprivateできます!
LinkedListのNodeクラスが良い例かもですね