🖐️

トップレベルクラスと内部クラスの修飾子への理解

に公開

はじめに

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