superの使い方 - 萌えJava超入門
クラスの継承

superの使い方

スーパークラスのメンバを参照する

super
目次

1. super の使い方


super() がスーパークラスのコンストラクタを示すことは、すでに紹介させて頂いた通りですが、
super はコンストラクタ以外にも、スーパークラスのメンバを表すことができます。

super の使い方
super()スーパークラスのコンストラクタ
super.変数名スーパークラスの変数
super.メソッド名()スーパークラスのメソッド




2. スーパークラスのメソッド


重要
super.メソッド名() は、オーバーライドされる前のメソッド

Animal_01.java(再出)
//Animal_01.java

public class Animal_01{

      protected static String group = "生き物です。";
      protected String name;

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

萌えJava超入門
この書き方は
実践でも使える。
//Dog_11.java

public class Dog_11 extends Animal_01{

    public Dog_11(String name){
        super(name);
    }
    @Override
    public void printName(){
        System.out.println("ジャジャーン!");
        super.printName();
        System.out.println("なんちゃって。");
    }
}

萌えJava超入門 萌えJava超入門
オーバーライドした
printNameメソッドの中で、
super.printName()
萌えJava超入門
そう。
スーパークラスのメソッドに
処理を付け足したいとき
便利だ。
重要
 super.メソッド名() は、メソッドの先頭である必要はありません。
 super.メソッド名() は、異なるメソッドの中でも使用できます。

//Driver_11.java

public class Driver_11{

    public static void main(String[] args){
        Dog_11 dog = new Dog_11("フレンダー");
        dog.printName();
    }
}

Animal_01.java、
Dog_11.java、
Driver_11.java、の3つのファイルを
wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_11.java
ws>java Driver_11
ジャジャーン!
フレンダーだぞ! ガオー!     ← super.printName()
なんちゃって。




3. スーパークラスの変数


重要
super.変数 と、this.変数 は共存できる
できるだけ避けてください。

サブクラスで、スーパークラスの変数と同名の変数を宣言すると、
サブクラスでは、super.変数 と、this.変数 が 共存するようになります。

クラスを指定しないで変数を使うと、サブクラスの変数 this.変数 が優先されます。
萌えJava超入門 萌えJava超入門
これってさぁ、
「ローカル変数とクラス変数を
同じ名前で宣言するな」
って話と同じ話?



萌えJava超入門

同じ話。


4. 実験


理解を深めるために、ちょっと実験してみましょう。
Dog_12クラスは、Animal_01クラスのサブクラスです。
Dog_12クラスで、Animal_01クラスと同名の変数「name」を宣言しました。
Dog_12クラスでは、this.namesuper.name が共存します。

萌えJava超入門
これは実験のためのサンプルだ。
マネしちゃダメなやつね。
//Dog_12.java

public class Dog_12 extends Animal_01{

    protected String name; //スーパークラスと同名の変数
    public Dog_12(String name){
        super(name);
    }
    public void printSuper(){
        System.out.println("this.name: " + this.name);
        System.out.println("super.name: " + super.name);
    }
}


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

萌えJava超入門
継承って
こうゆうことか!
萌えJava超入門 萌えJava超入門
Dog_12 のイメージ
  //Dog_12.java

  public class Dog_12 extends Animal_01{
      protected String name;
      //super.name;   ←見えていないけどいる。
      public Dog_12(String name){
          super(name); //super なので、super.name に代入。
      }

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

      public void printSuper(){
          System.out.println("this.name: " + this.name);
          System.out.println("super.name: " + super.name);
      }
  }

以下のように、Dog_12クラスをインスタンス化しました。
引数「"フレンダー"」が代入されるのはどこでしょう?
//Driver_12.java

public class Driver_12{

    public static void main(String[] args){
        Dog_12 dog = new Dog_12("フレンダー");
        dog.printName();
        System.out.println("-----------------------");

        dog.printSuper();
    }
}

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_12.java
ws>java Driver_12
フレンダーだぞ! ガオー!
-----------------------
this.name: null
super.name: フレンダー

「"フレンダー"」は、super(name); によって、super.name の方に代入されました。
printName()は、スーパークラスから継承されたので super.name を参照しています。
「フレンダーだぞ! ガオー!」は、正しく表示されています。

this.name は使われていません。



今度は printName() をオーバーライドして、変数 name を参照しています。

//Dog_13.java

public class Dog_13 extends Animal_01{

    protected String name; //スーパークラスと同名の変数
    public Dog_13(String name){
        super(name);
    }
    @Override
    public void printName(){
        System.out.println(name + "だワン!"); //この name は this.name
    }

    public void printSuper(){
        System.out.println("this.name: " + this.name);
        System.out.println("super.name: " + super.name);
    }
}

//Driver_13.java

public class Driver_13{

    public static void main(String[] args){
        Dog_13 dog = new Dog_13("フレンダー");
        dog.printName();
        System.out.println("-----------------------");

        dog.printSuper();
    }
}

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_13.java
ws>java Driver_13
nullだワン!
-----------------------
this.name: null
super.name: フレンダー


「"フレンダー"」は、Dog_12クラスと同様に、super(name); によって、
super.name に代入されました。

そして、サブクラスの printName()で参照しているのは、this.name です。
this.name は、初期値のままなので、 「nullだワン!」になってしまいました。

サブクラスで、うっかり同名の変数を宣言すると面倒です。
避けた方が無難でしょう。





お疲れ様でした。




© 2019 awasekagami