README
- この記事の内容はあくまで"Java Sivlerの試験で問題を解くためのもの"です
- 正しい情報ではないので注意
はじめに
経緯
Java Silverの勉強してる時に、Interfaceのdefaultメソッドの衝突問題が出てくる。
これがまあ自分にとっては分かりづらい。
自分の直感に対して、出力の違うことがいっぱいある。
そのため、自分のためにイメージ図を作成して覚えることにした。
ゴール
以下のようなコードの挙動が説明できるようにする。
- 親クラスのInterface vs 子のInterface
interface InterfaceWithSuper { default void hoge() {System.out.println("this is interfaceWithSuper hoge");} } interface InterfaceWithChild { default void hoge() {System.out.println("this is interfaceWithChild hoge");} } class Super implements InterfaceWithSuper{} class Child extends Super implements InterfaceWithChild{}; class Main{ public static void main(String[] args){ var a = new Child(); a.hoge(); // コンパイルエラー } }
アドホックな説明
クラスとは?
クラスは以下の3要素をまとめたもの
- メンバー変数 (属性)
- メソッド (操作)
- 親クラス
インターフェースとは?
インターフェースは実態を持たない。
インターフェースは「お前はこの操作(メソッド)を必ず作れよ」という口だけ野郎。
インターフェースのdefaultメソッドの場合はどうなる?(オーバーライドしないとき)
インターフェースのdefaultメソッドの場合は、 クラスのメソッドには追加されない。
クラスでメソッドが呼ばれた時に、
「俺持ってないメソッドあんねんけど貸してくれん??」みたいなノリで呼び出す。
親クラスにインターフェースを埋め込む時
親クラスに埋め込まれた時も、インターフェースは子供クラスにも貸し出せるようにしておく。
クラスのメソッドを呼び出す時の振る舞い
- 1.自分自身のメソッドを探す
- 2.親クラスのメソッドを探す (親クラスがさらなる親クラスを持っている場合は再起的に)
- 3.貸出可能なインターフェースの中から探す
じゃあ冒頭のコードはなぜエラーになるのか
1 自分のメソッドは定義されていない (defaultメソッドは借りてくるものなので、メソッドの中にはない)
2 親のメソッドを探すが、そこにもない
3 借りてくるためにインターフェースの中から探すが、2個あるのでエラーになる
まとめ(覚え方)
- オーバーライドしたメソッドは、「クラスに実装される」
- インターフェースのdefaultメソッドは 「クラスには実装されない」
- 必要な時に借りてくる
- メソッドの優先度は、
- ①自分自身
- ②親
- ③インターフェースが持ってるやつ