protected サブクラスからの参照 アクセス修飾子 - 萌えJava超入門
第十五章 アクセス修飾子

protected サブクラスからの参照

アクセス修飾子はクラスを継承する時の継承対象も制御します。

目次

1.アクセス修飾子 protected


 protected
 修飾子名 アクセス範囲適用対象
 protected  同一パッケージ内のクラスからアクセス可能
 サブクラスからのアクセス制限なし
メンバ
継承関係のないクラスから参照するのであれば、
protected は デフォルト(修飾子ナシ)と同じです。
このような場合は、紛らわしいので protected は使いません。
デフォルト で記述しましょう。
protected は継承されることを前提としたメンバに与えます。
継承とかサブクラスとか。
新しい言葉が出てきた。
少し説明しよう。


2.クラスの継承とは


ここではアクセス修飾子の視点で
クラスの継承を説明させてくれ。

了解しました。

クラスを作る際に、別のクラスのメンバを引き継いで、変更部分だけを記述する方法があります。
これがクラスの継承です。
元となるクラスをスーパークラス、受け継いだ先のクラスをサブクラスといいます。

重要
継承とは、別のクラスのメンバを引き継こと。

スーパークラスにあるメソッドとかが
何も書かずに使えるってことっスか?
ザックリそうゆうことだ。




むちゃくちゃ便利じゃ
ないっすか!!


3.継承の書式


extends スーパークラス名

クラスを継承する場合は、クラス名の後ろに「extends スーパークラス名」と記述します。
継承の書式
package パッケージ名;
import スーパークラスのパッケージ名.スーパークラス名;

class クラス名 extends スーパークラス名 {

}
同一パッケージ内であれば importを省略できます。

こんだけ?!



こんだけだ。


4.継承におけるアクセス制御


継承する場合にもアクセス修飾子がアクセスを制御します。
サブクラスからスーパークラスにアクセス可能であることに加えて、
スーパークラスにあるアクセスが許可されているメンバだけが、サブクラスで使用可能になります。

スーパークラスにある protected のメンバは、サブクラスからのアクセスを許可します。

重要
protected は異なるパッケージにあるサブクラスからのアクセスを許可します。

こんな感じになる。
スーパークラス例
package pk01;
public class ParentClass {
    protected static value01;
    protected static value02;
    protected static void method01(){}
    protected static void method02(){}
}

スーパークラス
継承元をスーパークラスと呼称しているだけで、特別なクラスではありません。
もちろん特別な記述も必要ありません。
 (逆に、継承を禁止したい場合は、クラスに final修飾子 を与えます。)
クラス外からアクセスできるように、
クラスとメンバに適切なアクセス修飾子を付与してください。

初心者の方は、
  クラスには public
  メンバには protected
を付与するといいでしょう。



サブクラス例
package pk_02;
import pk01.ParentClass;
class ChaildClass extends ParentClass {
    //処理 ParentClass のメンバがあるものとしてコーディングできます。
}

サブクラス
サブクラスは、extends スーパークラス と記述するだけです。
パッケージが異なる場合には、適宜 import スーパークラス; してください。
アクセスが許可されているスーパークラスのメンバが記載されているものとしてコーディングできます。



5.サンプルコード


ParentClassクラスがスーパークラス。
ChaildClassクラスは、ParentClassクラスのサブクラスです。
ChaildClassクラスで ParentClassクラスに記述されたメンバを使ってみましょう。

配置
   ws
    |---pk01
    |     └---ParentClass.java  ← スーパークラス(継承元)
    |
    └---pk02
          └---ChaildClass.java  ← サブクラス


//ParentClass.java
package pk01;

public class ParentClass{
    protected static void say(){
        System.out.println("ParentClass");
    }
}

//ChaildClass.java
package pk02;
import pk01.ParentClass;

class ChaildClass extends ParentClass{
    public static void main(String[] args){
        System.out.println("main method.");
        say();
    }
}

ParentClassが ChaildClassに継承されました。
ChaildClassに sayメソッドの記述はありませんが、
すでに記述があるものとして振る舞います。
コマンドライン
ws>javac pk02/ChaildClass.java
ws>java pk02.ChaildClass
main method.
ParentClass



6. NG例


sayメソッドのアクセス修飾子が
デフォルトだった場合を見てみよう。
重要
 デフォルト は異なるパッケージにあるクラスからのアクセスを禁止します。
 サブクラスからのアクセスであっても同様です。

以下のサンプルでは、public の ParentClass_Bクラスにはアクセスできていますが、
sayメソッドにはアクセスできませんでした。

配置
   ws
    |---pk01
    |     └---ParentClass_B.java  ← スーパークラス(継承元)
    |
    └---pk02
          └---ChaildClass_B.java  ← サブクラス


//ParentClass_B.java
package pk01;

public class ParentClass_B{
    static void say(){//アクセス修飾子がデフォルト
        System.out.println("ParentClass_B");
    }
}
ParentClass_B と ChaildClass_B が同一パッケージ内であれば動作します。

//ChaildClass_B.java
package pk02;
import pk01.ParentClass_B;

class ChaildClass_B extends ParentClass_B{
    public static void main(String[] args){
        System.out.println("main method.");
        say();//アクセスできない
    }
}

コマンドライン
ws>javac pk02/ChaildClass_B.java
pk02\ChaildClass_B.java:8: エラー: シンボルを見つけられません
        say();
        ^
  シンボル:   メソッド say()
  場所: クラス ChaildClass_B
エラー1個


ChaildClass_B(サブクラス)から
ParentClass_B(スーパークラス)の sayメソッドが
見えなくなってしまいました。

protected は
継承用なんスね。
ちょっとムズイっスね。

継承についてはいずれ別の機会に紹介させていただきます。




アクセス修飾子の説明はこれで終わりです。

お疲れ様でした。


© 2019 awasekagami