最初に
この記事は、以下の書籍を通じてJava silverの合格に向けて自分が学んだ内容を体系的にアウトプットする記事である。(目指せ年始合格!)
徹底攻略Java SE 11 Silver問題集[1Z0-815]対応
勉強記録
クラスの継承、インターフェース、抽象クラス
継承
- 継承していても引き継げないもの
- コンストラクタ
- privateなフィールドやメソッド
- クラスの多重継承禁止
- 継承関係にある二つのクラスで同名のフィールドがある場合
- フィールドを参照した場合は、インスタンスの型で宣言された方を使用
- メソッドを呼び出した場合は、メソッド内の指示に従う
- 参考)https://qiita.com/Shiho_anyplus/items/eabc380fcc8719ee4871
- 継承関係にあるクラスのコンストラクタの挙動
- スーパークラスのコンストラクタ呼び出しの後に、サブクラスのコンストラクタが呼び出しされる
- スーパークラスのコンストラクタ呼び出しの記述がない場合、コンパイラによって、サブクラスのコンストラクタの1行目にsuper()が自動で追加される
インターフェース
-
多重実現、多重継承ともにOK
-
メソッド
- アクセス修飾子は、publicのみ(記述しなくてもOK)
- 基本的に、処理の中身を一切記述できない(defalutメソッドは除く)
public interface Sample{ // 以下のように定義する(publicはなくても良い) public void hello(); // 以下は、コンパイルエラーとなる(処理なしという中身を持つと解釈されるため) public void hello(){} }
- 抽象メソッドは、インターフェースを実現したクラスが、必ず実装しなければならない(defalutメソッドは除く)
-
defaultメソッド
- インターフェースに処理の中身を記述できる
- インターフェースを実現したクラスが、実装する必要もない
public interface Sample{ defalt void print(int num){ System.out.println(num); } }
- java.lang.Objectクラスに定義されているメソッドは、defautメソッドとしてオーバーライドできない
- defaultメソッドをオーバーライドしたメソッドから、元のdefaultメソッドを呼び出す場合
インターフェース名.super.メソッド名(); // 正し、直接実現したクラスのみ呼び出し可能 // 2つ以上の実現や継承の階層を跨いでの呼び出しは不可
-
フィールド
- 定数のみ(finalを必ずつける)
- インスタンスを生成しなくても使える(staticを必ずつける)
オーバーライド
- 3つのルール
- シグニチャ(メソッド名+引数)が同じであること
- 戻り値型は、同じか、サブクラス型であること
- アクセス修飾子は、同じかより緩いものを指定すること
型変換
-
スーパークラス型をサブクラス型に、インターフェース型を実装クラス型に変換する際は、明示的にキャスト式を記述する必要がある(アップキャストは明示不要だが、ダウンキャストは明示必要)
public class A{ //処理 } public class B extends A{ //処理 } public static void main(String[] args){ //アップキャストは明示不要 A a = new B(); //ダウンキャストは明示必要 B bOk = (B)a; //以下はNG B bNg = a; }
-
型同士に互換性がない場合の型変換は、コンパイルエラーではなく、例外となる
public class A{ public void print(){ System.out.println("A"); } } public class B extends A{ public void print(){ System.out.println("B"); } } public static void main(String[] args){ A a = new A(); //キャストにより、互換性の保証をしているため、コンパイルエラーとはならない B b = (B)a; //しかし、aは、Aのインスタンスのため、AとBの処理内容の差分を含んでおらず、Bでオーバーライドしたメソッドを実行できない b.hello(); }
感想
- 抽象クラスと実現、Java silverの問題を解く分には問題なさそうなくらいの理解度だが、自分で0からインターフェースや抽象クラスを設計するとなるとまだ不安が残る理解度というのが正直なところ。思えば、過去2年で自分が携わった開発案件は、すでにクラス設計が固まっていたサービスだったので、なぜ抽象クラスやインターフェースでこの処理を扱っているかというところに着目せずにcodingしていた気がする。自分で0から作り上げる経験を積む必要があるなと感じた。