🖐️
トップレベルクラスと内部クラスの修飾子への理解
はじめに
Java Silver の模擬問題を解いていて、「え、なんでこれコンパイルエラーなん?」
となる代表格が クラスの修飾子問題 です。
この記事では、
トップレベルクラスで使える修飾子
内部クラスで急に自由度が上がる理由
「extends は正しそうなのに不正解」になる正体を一気に整理します。
そもそもサブクラスとは?
class B extends A {}
この B が A のサブクラス です。
ここまでは誰でも分かる。
問題は「どこに書くか」と「修飾子」。
トップレベルクラス(ファイル直下)で使える修飾子
使えるもの
public class B extends A {}
class B extends A {} // package-private
final class B extends A {}
使えないもの(即コンパイルエラー)
private class B extends A {} // ❌
protected class B extends A {} // ❌
static class B extends A {} // ❌
覚え方
トップレベルクラスは public か何も書かないだけ
final は OK(継承を止めるだけなので)
トップレベルクラス(ファイル直下)で使える修飾子
理由は単純です。
トップレベルクラスには「外側」が存在しない
スコープを制御できない修飾子は使えない
つまり、
守る人(外側のクラス)がいないから private にできない
内部クラスになると大きく変わります。
class Outer {
private class Inner extends A {}
protected class Inner2 extends A {}
static class Inner3 extends A {}
}
Outer がスコープを管理してくれるから
内部クラスは「Outer の持ち物」
だから修飾子フル装備が許される。
内部クラスは継承できるのか?
答えは 修飾子次第。
例① private 内部クラス
class Outer {
private class Inner extends A {}
}
Outer の外からは 見えない
継承不可
例② public 内部クラス
class Sub extends Outer.Inner {} // OK(Outer のインスタンス前提)
👉 内部クラスだから継承できる/できないではない
👉 アクセス修飾子で決まる
試験での最重要チェックポイント
二度と引っかからないためのチェックリスト
トップレベルクラスなら
private / protected / static が見えたら即 NG
public or 何もなしだけ
内部クラスなら
修飾子は全部あり得る
継承可否は public / protected かどうか
| 修飾子 | 同一クラス | 同一パッケージ | サブクラス | 他パッケージ |
|---|---|---|---|---|
| public | ○ | ○ | ○ | ○ |
| protected | ○ | ○ | ○ | × |
| (なし)package-private | ○ | ○ | × | × |
| private | ○ | × | × | × |
これを参考にどこで何を使うかを参考に!
Discussion