1
2

More than 3 years have passed since last update.

Java Silver SE11 継承とオーバーライドの間違えやすい部分

Last updated at Posted at 2021-01-21

Java Silver SE11の問題を解いていて継承とオーバーライドに関する問題を間違えるので備忘録として残す。

大事なのは何の型で宣言されて、何のインスタンスを生成しているか。
メソッドはどのようなアクセス修飾子が付与されているか。

public class Main {
    public static void main(String[] args) throws Exception {
        //case A
        Super superClass = new Sub();

        //case B
        // Super superClass = new Super();

        Sub subClass = new Sub();

        //code 1
        // subClass = superClass;

        //code 2
        // subClass = (Sub)superClass;

        //code 3
        // superClass = subClass;

        superClass.print();
        subClass.print();
    }
}

class Super{
    //case C privateで修飾
    //case D staticで修飾
    void print(){
        System.out.println("Super");
    }
}

class Sub extends Super{
    //case D staticで修飾
    void print(){
        System.out.println("Sub");
    }
}

それぞれの実行結果がどうなるか。

  • case Aの場合

    • code 1の時
      サブクラス型の変数subClassにスーパークラス型の変数superClassを代入しているためコンパイルエラー
    • code 2の時
      スーパークラス型の変数superClassはSubクラスのインスタンス生成しているため、ダウンキャストされて代入される。実行結果はオーバーライドされたメソッドが優先されるので「Sub Sub」
    • code 3の時
      スーパークラス型の変数superClassにサブクラス型の変数subClassを代入しているため自動的にアップキャストされ、実行結果も同様にオーバーライドされたメソッドが優先されて「Sub Sub」
  • case Bの場合

    • code 1の時
      case Aの場合と同様にコンパイルエラー
    • code 2の時
      明示的にキャストしているためコンパイルエラーは起こらない。しかし、スーパークラス型の変数superClassはSuperクラスのインスタンスを生成しており、サブクラスの差分を持たないため、ClassCastExceptionがスローされる(実行時エラーが起きる)
    • code 3の時
      case Aの場合と同様にアップキャストされ、実行結果は「Sub Sub」
  • case Cの場合

    • スーパークラスであるSuperクラスのprintメソッドがprivateで修飾されると、オーバーライドされているとみなされず、生成されているインスタンスに関わらず、変数の型のprintメソッドが実行される。
  • case Dの場合

    • 両方のprintメソッドがstaticで修飾された場合、変数の型のprintメソッドが実行される。
    • staticで修飾する場合は両方のメソッドを修飾しないとコンパイルエラーになる。
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2