バナー画像

プログラムを実装する際、曖昧に設定しがちなアクセス修飾子ですがみなさんは適切に定義出来ているでしょうか?

本記事ではアクセス修飾子の中でも特に曖昧となりがちな「protected」の使い方についてご紹介していきます。

Javaのアクセス修飾子protectedとは

Javaにはクラスやフィールド、メソッドを定義する際に記述するアクセス修飾子という概念があります。

本記事のテーマである「protected」はアクセス修飾子の1つですが、まず基本的な考え方についてご紹介します。

アクセス修飾子についてまずは理解しよう!

Javaにはアクセス修飾子という考え方があり、クラスや定義されたフィールド・メソッドがアクセス可能な範囲を定義することが出来るものです。

「public」「private」「protected」「定義しない(デフォルト)」の4種類から記述することが可能です。

アクセス修飾子「protected」の役割は?

Javaのアクセス修飾子「protected」の説明として用いられるのは「同一パッケージまたはサブクラスからは参照可能」との表現です。

具体的には同一パッケージ内の「自クラス」「サブクラス」「他クラス」と他パッケージの「サブクラス」から参照が可能ということです。

ポテパンダの一言メモ

他パッケージに定義されたサブクラス以外のクラスからは参照することが出来ません。

Javaのサンプルコードでprotectedの使い方を確認しよう

ここからはサンプルコードを掲載しながら実際にJavaのプログラムでprotectedがどのように使用されるのか確認していきたいと思います。

同一パッケージの自クラスから参照する場合

下記のコードは同一パッケージ内の自クラスから各アクセス修飾子で定義したフィールドの値を出力するサンプルです。

import java.util.*;

public class Main {
    
    public static String publicStr       = "publicのフィールドです。";
    private static String privateStr     = "privateのフィールドです。";
    protected static String protectedStr = "protectedのフィールドです。";
    static String defaultStr             = "defaultのフィールドです。";
    
    public static void main(String[] args) throws Exception {
        
        System.out.println(publicStr);
        System.out.println(privateStr);
        System.out.println(protectedStr);
        System.out.println(defaultStr);
    }
    
    
}

サンプルコードを実行した結果は下記の通りとなります。

publicのフィールドです。
privateのフィールドです。
protectedのフィールドです。
defaultのフィールドです。

同一パッケージ内の同一クラスからは問題なく「protected」の値を呼び出すことが可能であることをご確認いただけます。

同一パッケージ内のサブクラスから参照する場合

次にサブクラスからそれぞれのアクセス修飾子のフィールドを参照した場合のサンプルコードです。

import java.util.*;

public class Main extends SubClass {
    
    
    public static void main(String[] args) throws Exception {
        
        SubClass subClass = new SubClass();
        
        System.out.println(subClass.publicStr);
        // System.out.println(subClass.privateStr); サブクラスのprivateフィールドは参照不可
        System.out.println(subClass.protectedStr);
        System.out.println(subClass.defaultStr);
    }
}

class SubClass {
    public static String publicStr       = "publicのフィールドです。";
    private static String privateStr     = "privateのフィールドです。";
    protected static String protectedStr = "protectedのフィールドです。";
    static String defaultStr             = "defaultのフィールドです。";
}

サンプルコードを実行した結果は下記の通りとなります。

privateで定義したフィールドに関してはエラーとなるためコメントアウトしています。

publicのフィールドです。
protectedのフィールドです。
defaultのフィールドです。

異なるパッケージのサブクラスから参照する場合

別パッケージのサブクラスから参照する場合のサンプルは下記の通りとなります。

「同一パッケージのサブクラスから参照する場合」でのサンプルコードをファイル分割したものとなります。

「Main.java」でファイルを作成しています。

package sample;

import java.util.*;
import test.SubClass;

public class Main extends SubClass {


    public static void main(String[] args) throws Exception {

        SubClass subClass = new SubClass();

        System.out.println(subClass.publicStr);
        // System.out.println(subClass.privateStr); サブクラスのprivateフィールドは参照不可
        System.out.println(subClass.protectedStr);
        // System.out.println(subClass.defaultStr); サブクラスのデフォルトフィールドは参照不可
    }
}

「SubClass.java」でファイルを作成しています。

package test;

public class SubClass {
    public static String publicStr       = "publicのフィールドです。";
    private static String privateStr     = "privateのフィールドです。";
    protected static String protectedStr = "protectedのフィールドです。";
    static String defaultStr             = "defaultのフィールドです。";
}

サンプルコードを実行した結果は下記の通りとなります。

publicのフィールドです。
protectedのフィールドです。

別パッケージに作成した「SubClass」ですが、「Main.java」で継承しているため「protected」のフィールドの値が出力されることを確認出来ます。

異なるパッケージの他クラスから参照しようとした場合

では継承を使用せずに別パッケージの他クラスから参照しようとした場合はどうなるのでしょうか?

答えはコンパイルエラーとなり、実行する事が出来ません。

下記のサンプルコードで確認してみてください。

「Main.java」でファイルを作成しています。

package sample;

import java.util.*;
import test.SubClass;

public class Main {


    public static void main(String[] args) throws Exception {

        SubClass subClass = new SubClass();

        System.out.println(subClass.publicStr);
        // System.out.println(subClass.privateStr); サブクラスのprivateフィールドは参照不可
        System.out.println(subClass.protectedStr);
        // System.out.println(subClass.defaultStr); サブクラスのデフォルトフィールドは参照不可
    }
}

「SubClass.java」でファイルを作成しています。

package test;

public class SubClass {
    public static String publicStr       = "publicのフィールドです。";
    private static String privateStr     = "privateのフィールドです。";
    protected static String protectedStr = "protectedのフィールドです。";
    static String defaultStr             = "defaultのフィールドです。";
}

サンプルコードをコンパイルしようとすると下記のようなエラーが表示されます。

sample/Main.java:15: エラー: protectedStrはSubClassでprotectedアクセスされます
        System.out.println(subClass.protectedStr);

上記のコンパイルエラーは、アクセス修飾子「protected」が許可している範囲外(他パッケージのサブクラス以外)からアクセスしようとしているため、コンパイルエラーとなっています。

さいごに:Javaのアクセス修飾子protectedを理解してオブジェクト指向をより深く理解しよう!

本記事では、Javaのアクセス修飾子「protected」の使い方についてご紹介してきました。

オブジェクト指向をうまく活用してプログラムを組んでいくためにはアクセス修飾子「protected」の理解は欠かせません。

ぜひ、実用的で可読性の高いプログラムを実装するために、アクセス修飾子「protected」を理解し、Javaのオブジェクト指向をより深く理解してみてください。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。