継承におけるアクセス制御 - 萌えJava超入門
クラスの継承

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

継承させたいメンバは protected で書きましょう

× private
○ protected

目次

1. 継承するなら protected 以上

スーパークラスを作る際には、メンバのアクセス修飾子に注意してください。
private は、継承先(サブクラス)からアクセスすることができません。

カプセル化の観点から、インスタンス変数に private を付与するのは
とても良いことです。
ただ、継承先に新しいメソッドを作って、そこから参照したい変数には、
protected 以上のアクセス修飾子を付与する必要があります。

萌えJava超入門 萌えJava超入門
protected
初耳っすね。
萌えJava超入門
あ、えっと、
実は、むか~し出てきた。
ホントさわりだけ。
アクセス制御
 スーパークラスの private なメンバは、サブクラスから参照できません。
 protected を活用しましょう。




2. privateでも動作する例


private修飾子を使ってちょっとだけ実験してみましょう。
萌えJava超入門
Animal_pv01クラスは
変数「name」を private
書いてある。
継承するとどうなるか実験してみよう。
//Animal_pv01.java

public class Animal_pv01{

      private static String group = "生き物です。";
      private String name; //サブクラスから参照できません

      public Animal_pv01(){
          this("無名");
      }
      public Animal_pv01(String name){
          this.name = name;
      }
      public static void printGroup(){
          System.out.println(group);
      }
      public void printName(){
          System.out.println(name + "だぞ! ガオー!");
      }
}

萌えJava超入門
サブクラス(Dog_pv01)で
super.name を参照していないから
これはセーフ。
//Dog_pv01.java
public class Dog_pv01 extends Animal_pv01{
    public Dog_pv01(String name){
        super(name);
    }
}

↓↓↓ 以下のようなイメージ。↓↓↓

Dog_pv01 のイメージ
  //Dog_pv01.java

  public class Dog_pv01 extends Animal_01{
      public Dog_pv01(String name){
          super(name);
      }

      // ↓見えていないけどいる。
      @Override
      public void printName(){
          //super.printName() の中で super.name を参照
          super.printName();
      }
  }

//Driver_pv01.java

public class Driver_pv01{

    public static void main(String[] args){
        Dog_pv01 dog01 = new Dog_pv01("白いお父さん");
        //このprintName() は super.printName()を呼んでいる
        dog01.printName();
    }
}

Animal_pv01クラス、
Dog_pv01クラス、
Driver_pv01クラス、を
wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_pv01.java
ws>java Driver_pv01
白いお父さんだぞ! ガオー!

super.printName()メソッドから super.name変数を参照するので、
nameprivate で問題ありません。
super.printName()メソッド自体は public である点もポイントです。

萌えJava超入門 萌えJava超入門
スーパークラス内での
参照なのね。


3. privateでは動作しない例


引き続き privateで実験です。
萌えJava超入門
これはアウトだ。
サブクラス(Dog_pv02)で
super.name を参照している。
//Dog_pv02.java
public class Dog_pv02 extends Animal_pv01{
    public Dog_pv02(String name){
        super(name);
    }
    @Override
    public void printName(){
        //サブクラスから super.name を参照
        System.out.println(name + "だワン!"); //super.name
    }
}
萌えJava超入門 萌えJava超入門
Dog_pv02 の printName()
super.name を参照してるのね。

//Driver_pv02NG.java

public class Driver_pv02NG{

    public static void main(String[] args){
        Dog_pv02 dog02 = new Dog_pv02("白いお父さん");
        dog02.printName();
    }
}

Animal_pv01クラス、
Dog_pv02クラス、
Driver_pv02NGクラス、を
wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_pv02NG.java

.\Dog_pv02.java:9: エラー: nameはAnimal_pv01でprivateアクセスされます
        System.out.println(name + "だワン!"); //super.name
                           ^
エラー1個


Dog_pv02.printNameメソッドに記述されている name は、super.nameです。
(Dog_pv02クラスに name変数の宣言が無いため、継承された super.name を示す)
private なので、サブクラスからのアクセスはできません。

萌えJava超入門 萌えJava超入門
継承元のクラスでは、
とりあえず
protectedを使えばいいんすね。
萌えJava超入門
えっと、
そんな感じです。



お疲れ様でした。




© 2019 awasekagami