【解決Java】アクセス修飾子(protected、privateなど)

こんにちは!侍エンジニア インストラクターの本多です。みなさんは、クラスやメソッド、変数のアクセス修飾子を適切に付与していますか?

Javaのアクセス修飾子とは、名称の前に付いているprivateやpublicなどです。この記事では、アクセス修飾子について

  • アクセス修飾子とは何か
  • アクセス修飾子のスコープ一覧
  • private、publicの使い方

という基本的な内容から、

  • protectedの使い方
  • protectedの注意点

といった応用的な内容に関しても解説していきます。今回はアクセス修飾子について、使い方をわかりやすく解説します!

なお、Javaの記事については、こちらにまとめています。

目次

アクセス修飾子とは

例えば2、300行や1000行以上の長いプログラムになってくると、プログラムが別プログラムを呼び、、、という構造になっています。教育用やサンプル用プログラムでないかぎり、1つのプログラムで事足りるということはまずありません。

もちろん、Javaもさまざまな要素が組み合わさって、つまりメソッドやクラスが別の何かを呼んで、、、という構造になっています。

では、どこからでも何でもアクセスできるのかというと、そうではありません。インスタンス内部の変数は、モノによっては他のインスタンスから書き込みさせたくない、という場合もあります。

例えばループカウンタを外部から書き換えられてしまうと、とんでもない誤動作を引き起こすでしょう。

逆に、広く使ってほしい変数やメソッドは、制限をかけてはいけません。誰もアクセスできない共通メソッド、というのも変ですよね。そういった、アクセスの制限をコントロールするものをアクセス修飾子と呼びます

アクセス修飾子のスコープ一覧

アクセス修飾子には、

  • public
  • protected
  • 指定なし(デフォルト)
  • private

の4種類があります。

変数やメソッドにはこの4種類すべてのアクセス修飾子を付けることができます。クラスにはpublicを付けたり、指定なしとすることができますが、protectedやprivateを付けることはできません。

アクセス修飾子を付けてアクセスできる範囲をスコープと呼びます。以下のように表にまとめました。

アクセス修飾子のスコープ(アクセスレベル)一覧:

アクセス修飾子同一クラス同一パッケージサブクラスすべて
public
protected×
指定なし(デフォルト)××
private×××

publicのスコープが一番広く、どのクラスからも参照可能です。

これに対し、privateのスコープが最も狭く、同一のクラスからしか参照できません。

privateの使い方

不用意に外部からのアクセスを許さず、かつ外部からは決められたメソッドからのみアクセスさせたい場合、アクセス修飾子はprivateを使います。では早速、実際のコードを使って説明します。

// クラス名:PublicClass
class PublicClass {
    private String fieldVariable = "PublicClassのフィールド変数.";
    
    public void publicMethod() {
        System.out.println(fieldVariable + "publicMethodより出力.");
    }
}

public class Main {
 
    public static void main(String[] args) {
        PublicClass pc = new PublicClass();
        pc.publicMethod();
    }
 
}

実行結果:

PublicClassのフィールド変数.publicMethodより出力.

このサンプルコードではfieldVariableがprivateで直接アクセスできないため、publicMethod経由でアクセスしています。

publicの使い方

publicというのは、事実上制限がかかっていない状態と思って問題ありません。先ほどのサンプルプログラムではfieldVariableがprivateのためpublicMethod経由でアクセスしました。

今度はpublicに変更して直接アクセスしてみます。

// クラス名:PublicClass
class PublicClass {
    public String fieldVariable = "PublicClassのフィールド変数.";
    
    public void publicMethod() {
        System.out.println(fieldVariable + "publicMethodより出力.");
    }
}

public class Main {
 
    public static void main(String[] args) {
        PublicClass pc = new PublicClass();
        System.out.println(pc.fieldVariable);
    }
 
}

実行結果:

PublicClassのフィールド変数.

fieldVariableがpublicなので、publicMethod経由でなくてもアクセスできます。このようにして、publicなら外部から自由にアクセスできることが確認できました。

アクセス修飾子の概要、分かっていただけたでしょうか?

protectedの使い方

privateとpublic以外に、protectedというアクセス修飾子があります。定義的には以下になります。

  • メソッド、変数のみ付与できる。
  • 同一クラス、同一パッケージ、サブクラスから参照できる。

サブクラスから参照

サブクラスから参照する場合について、実際にコードを使って説明します。

class SuperClass {
    protected String str = "SuperClassの変数";
}

public class SubClass_OK1 extends SuperClass {
 
    public static void main(String[] args) {
        SubClass_OK1 sc = new SubClass_OK1();
        System.out.println(sc.str);
    }
 
}

実行結果:

SuperClassの変数

クラスSubClass_OK1は、クラスSuperClassを継承しているので、SuperClass内の変数strにアクセス可能です。

同一クラスから参照

同一クラスから参照する場合について、サンプルコードで確認していきましょう。

public class SubClass_OK2{
 
    public static void main(String[] args) {
        method();
    }

    protected static void method() {
        System.out.println("protectedが付いたメソッド");
    } 
}

実行結果:

protectedが付いたメソッド

アクセスできない場合

では、アクセスできない場合についてです。以下の例ではエラーになりますので注意しましょう。

class SuperClass {
    protected String str = "SuperClassの変数";
}

class SubClass_NG {
 
    public static void main(String[] args) {
        SubClass_NG sc = new SubClass_NG();
        System.out.println(sc.str);
    }
 
}

実行結果:

SubClass_NG.java:9: error: cannot find symbol

SuperClassの変数strはprotectedになっているので、継承関係は無いことからアクセスできずにエラーになります。

まとめ

この記事ではアクセス修飾子について解説しました。アクセス修飾子の役割は、エラーを未然に防いだりセキュリティの問題点を解消したり、とさまざまです。Javaを使ってコーディングする上では避けて通れません。

実際に使うことがあってもよく分からなかったら、本記事を思い出してくださいね!

この記事を書いた人

関西在住のITエンジニアです。普通の会社に勤務しながら、侍エンジニアのインストラクター、ライターとして活動しています。

目次