カテゴリ: JavaSilver試験対策 更新日: 2026/06/06

Javaのアクセス制御とパッケージの基本を完全解説!初心者向け入門ガイド

006
Javaのアクセス制御とパッケージの基本

先生と生徒の会話形式で理解しよう

生徒

「Javaで、あるクラスを別のクラスで継承して使おうとしたら、コンパイルエラーになったんです。何が問題だったんでしょうか?」

先生

「それはパッケージの扱いやアクセス制御に関係している可能性が高いですね。パッケージやアクセス修飾子の基本ルールを一緒に確認してみましょう。」

生徒

「はい!そのあたりのルールを詳しく知りたいです。」

先生

「では、具体的な例を交えて説明していきますね。」

1. パッケージとアクセス制御の基本

1. パッケージとアクセス制御の基本
1. パッケージとアクセス制御の基本

Javaでは、クラスはパッケージと呼ばれるグループに属します。パッケージは、クラスを整理し、名前の衝突を防ぐために使われます。クラス間でアクセスできる範囲は、アクセス修飾子によって制御されます。

主なアクセス修飾子とその範囲は次の通りです。

  • public: どこからでもアクセス可能
  • protected: 同じパッケージ内、または他パッケージのサブクラスからアクセス可能
  • なし(デフォルト): 同じパッケージ内でのみアクセス可能
  • private: 同じクラス内でのみアクセス可能

2. 無名パッケージと明示的なパッケージの違い

2. 無名パッケージと明示的なパッケージの違い
2. 無名パッケージと明示的なパッケージの違い

Javaでは、パッケージ宣言がないクラスは無名パッケージに属します。一方、packageキーワードを使って宣言されたクラスは明示的なパッケージに属します。

たとえば、以下のようなクラスは無名パッケージに属しています。


public class User {
    protected String name = "John";
}

一方、次のクラスはmyappというパッケージに属しています。


package myapp;

public class UserManager {
    public static void main(String[] args) {
        User user = new User(); // コンパイルエラー
    }
}

この場合、Userクラスは無名パッケージに属しているため、明示的にパッケージが指定されたUserManagerクラスからアクセスできません。

3. パッケージが異なる場合のアクセス制御

3. パッケージが異なる場合のアクセス制御
3. パッケージが異なる場合のアクセス制御

クラスを別のパッケージで使う場合、アクセス制御のルールが適用されます。たとえば、次のようなコードを見てみましょう。


package myapp;

public class Admin {
    protected int level = 5;
}

package myapp.utils;

import myapp.Admin;

public class AdminHelper extends Admin {
    public static void main(String[] args) {
        System.out.println(level); // コンパイルエラー
    }
}

このコードでは、AdminHelperAdminを継承していますが、levelフィールドには直接アクセスできません。理由は、protectedなフィールドは「サブクラス内であっても、インスタンスを介してのみアクセス可能」だからです。

解決するには、以下のようにインスタンスを介してアクセスします。


public class AdminHelper extends Admin {
    public static void main(String[] args) {
        AdminHelper helper = new AdminHelper();
        System.out.println(helper.level); // 5と表示される
    }
}

Javaをこれから始める人や、 オブジェクト指向の考え方を基礎から理解したい人には、 定番の入門書がこちらです。

スッキリわかるJava入門 第4版をAmazonで見る

※ Amazon広告リンク

4. 問題のポイントを理解する

4. 問題のポイントを理解する
4. 問題のポイントを理解する

設問のコードでは、無名パッケージに属するクラスと明示的なパッケージに属するクラスの間でアクセスしようとしているため、コンパイルエラーが発生しました。これは、無名パッケージのクラスは同じ無名パッケージ内でしかアクセスできないからです。

アクセス制御やパッケージの違いを正しく理解し、エラーを防ぐことが大切です。

5. パッケージ宣言とディレクトリ構造のルール

5. パッケージ宣言とディレクトリ構造のルール
5. パッケージ宣言とディレクトリ構造のルール

Javaでパッケージを利用する際、ソースコードの先頭に書く package 宣言と、実際のコンピュータ上のフォルダ(ディレクトリ)構造は必ず一致していなければなりません。

例えば、package com.example.project; と宣言したクラスファイルは、必ず com/example/project という階層のフォルダ内に保存する必要があります。このルールを無視すると、コンパイラがクラスを見つけることができずエラーになります。

  • 階層管理: ドット(.)で区切られた名前がフォルダの階層に対応します。
  • 重複回避: 世界中で使われるライブラリと名前がぶつからないよう、会社ドメインを逆にした名前(com.google...など)を使うのが一般的です。

6. 他のパッケージのクラスを利用する「import」の使い方

6. 他のパッケージのクラスを利用する「import」の使い方
6. 他のパッケージのクラスを利用する「import」の使い方

別のパッケージにある public なクラスを使いたいときは、import 文を使って「このパッケージのこのクラスを使います」と宣言する必要があります。

未経験の方が間違いやすいポイントですが、同じパッケージ内のクラスであれば import は不要です。しかし、パッケージが分かれた瞬間に、たとえ public であっても明示的なインポートが必要になります。


package myapp.main;

// 他のパッケージからクラスを呼び出す
import myapp.model.User; 

public class App {
    public static void main(String[] args) {
        // importしているから、Userクラスが使える
        User user = new User();
        System.out.println("ユーザー機能を開始します。");
    }
}

もし import を忘れると、「型を解決できません」というエラーが発生します。Eclipseなどの開発ツールを使えば、自動で import 文を生成してくれる便利な機能もあります。

7. パッケージによるアクセス制御のメリット

7. パッケージによるアクセス制御のメリット
7. パッケージによるアクセス制御のメリット

なぜわざわざパッケージを分けてアクセスを制限するのでしょうか?それは、大規模なプログラムになればなるほど、「どこからでも触れる変数」がバグの温床になるからです。

  • 内部処理の隠蔽: 外部に公開する必要のないクラスやメソッドを「無名(デフォルト)」アクセスにすることで、パッケージ外からの不用意な操作を防げます。
  • 役割の明確化: controllermodelview のようにパッケージを分けることで、プログラムのどこに何が書いてあるか整理しやすくなります。

最初はすべてのクラスを同じ場所に置いてしまいがちですが、機能ごとにパッケージを分ける習慣をつけることで、設計の綺麗な、壊れにくいプログラムを書けるようになります。

まとめ

まとめ
まとめ

Javaのアクセス制御とパッケージについて、基本的なルールから具体例までを解説しました。重要なポイントは、無名パッケージのクラスは同じ無名パッケージ内でしかアクセスできないこと、protectedはサブクラス内でインスタンスを介してのみアクセスできることです。 また、パッケージの違いによってクラス間のアクセスが制限されるケースを学びました。この知識を活用して、Javaでの開発を効率的に進めていきましょう。

以下は、まとめとして、protectedなフィールドをサブクラス内で適切にアクセスする例です。


package example;

public class Parent {
    protected String message = "Hello from Parent!";
}

package example;

public class Child extends Parent {
    public void printMessage() {
        System.out.println(this.message); // 正しくアクセス
    }

    public static void main(String[] args) {
        Child child = new Child();
        child.printMessage(); // Hello from Parent!
    }
}

このように、protectedなフィールドは、サブクラス内でthisキーワードを使うことでアクセスできます。この仕組みを理解すれば、適切なアクセス制御を行いながらクラスを設計できます。

先生と生徒の振り返り会話

生徒

「パッケージの違いやアクセス制御のルールが分かりました!特にprotectedの使い方がポイントですね。」

先生

「その通りです。protectedは、サブクラスで使うための便利な修飾子ですが、同じパッケージ内の他のクラスからもアクセスできる点に注意が必要です。」

生徒

「無名パッケージのクラスが他のパッケージからアクセスできない理由も理解できました。」

先生

「良かったです!Javaではパッケージ設計が非常に重要なので、今回学んだルールを活用して効率的なコードを書きましょう。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Javaのアクセス修飾子にはどんな種類がありますか?それぞれの意味も教えてください。

Javaのアクセス修飾子には、public(全てからアクセス可能)、protected(同じパッケージ内または他パッケージのサブクラスからアクセス可能)、デフォルト(同一パッケージ内のみアクセス可能)、private(同一クラス内のみアクセス可能)があります。

Javaでクラスが属するパッケージって何ですか?

Javaのパッケージとは、クラスを整理するためのフォルダのような仕組みです。クラスをグループ化し、名前の衝突を防いだり、アクセス制御に利用されたりします。

Javaでアクセス修飾子を指定しないとどうなりますか?

アクセス修飾子を指定しない場合、デフォルトアクセス(パッケージプライベート)となり、同じパッケージ内のクラスからのみアクセスできます。他のパッケージからはアクセスできません。
JavaSilver試験対策の一覧へ
新着記事
Java
Javaの演算子の優先順位
Javaの演算子の優先順位を完全解説!初心者向けの丁寧な解説
Java
Javaのローカル変数と順次処理
Javaのローカル変数と順次処理を徹底解説!初心者でも理解できるコードの基本
Python
NumPyのdtype一覧!int・float・bool・str・objectの違いを比較
NumPyのdtype一覧を完全解説!int・float・bool・str・objectの違いを初心者向けに比較
Dart
Dartのコンストラクタまとめ!デフォルト・名前付きコンストラクタの使い方
Dartのコンストラクタまとめ完全ガイド!デフォルトコンストラクタと名前付きコンストラクタの使い方を初心者向けに解説
人気記事
Java
Java の Random クラスを使ってランダムな数値を生成する方法
JavaのRandomクラスの使い方を完全ガイド!初心者でもわかる乱数生成
Java
Java の getter メソッドと setter メソッドの使い方
Javaのgetterメソッドとsetterメソッドの使い方を完全ガイド!初心者でもわかるアクセス方法
AWS
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説
Flutter
Flutter SDKのダウンロードとインストール手順を詳しく解説
Flutter SDKのダウンロードとインストール手順を丁寧ガイド!初心者でも安心な環境構築

🔌 USBポート不足を解消

Type-C 1本で拡張。
開発・作業環境を一気に快適に

UGREEN USB-Cハブを見る

※ Amazon広告リンク