継承時のアクセス制御

広告

メンバ変数やメンバメソッドに対するアクセス制限に関しては『publicとprivate』でも記述した通り「public」を付けた場合(又はアクセスに関する修飾子を省略した場合)は、クラス外からでも直接アクセスが可能です。また「private」を付けた場合はクラス内からしかアクセスが出来ません。

そこでスーパークラスのメンバ変数やメソッドに「private」を付けた場合、そのスーパークラスを継承したサブクラスからは呼び出しができるかどうか試してみます。下記のような簡単なサンプルを作成し、スーパークラス内で定義されたpublicメンバとprivateメンバに、それぞれサブクラス内からアクセスしてみます。

class ctest12{
  public static void main(String args[]){
    B sample = new B();
  }
}

class A{
  public int var = 0;
  private int varErr = 0;

  public int get(){
    return var;
  }

  private int getError(){
    return var;
  }
}

class B extends A{
  public void getVar(){
    System.out.println("値:" + var);
    System.out.println("値:" + varErr);
    System.out.println("値:" + get());
    System.out.println("値:" + getError());
  }
}

実際にコンパイルしてみると下記のようにコンパイルの時点でエラーとなります。

p2

このようにサブクラス内からもprivateなメンバ変数やメンバメソッドにはアクセスできません。当然のことながらサブクラスのオブジェクトからもアクセスは出来ません。

protected

アクセス修飾子にはもう1つ「protected」という修飾子があります。この修飾子はサブクラスからスーパークラスのメンバへアクセスが出来るという意味合いがある修飾子で「public」と同じような働きをします。

例えば下記のような例で考えて見ます。

class ctest13{
  public static void main(String args[]){
    B sample = new B();

    System.out.println("サブクラスからのアクセス");
    sample.getVar();

    System.out.println("他クラスからのアクセス");
    System.out.println("値:" + sample.get());
  }
}

class A{
  protected int var = 0;

  protected int get(){
    return var;
  }
}

class B extends A{
  public void getVar(){
    System.out.println("値:" + var);
    System.out.println("値:" + get());
  }
}

スーパークラス内で定義された「protected」なメンバ変数やメンバメソッドは、サブクラス内からもアクセスが出来ますし、他のクラス内からもアクセスが可能です。その為、ほぼ「public」相当の働きとなります。ただ意味合い的には継承されたサブクラス内からアクセスされるようなメンバに対して付けることになっていますので、「public」と「protected」は明確に分けて使います。

またパッケージという概念を使う場合には「public」と「protected」は異なる挙動を示します。「public」は異なるパッケージからでもアクセス可能ですが、「protected」は異なるパッケージからは「private」と同等となります。このあたりの詳しい内容はパッケージの説明の際に見ていきます。

ちなみに先ほどのサンプルを実際に実行すると下記のようになります。

p3

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)