読者です 読者をやめる 読者になる 読者になる

S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

継承した型によるオーバーロード、インターフェースだとどうなる?

技術メモ Java

昨日の続きで、インターフェースの場合どうなるのか確認してみた。
Java 6u33


インターフェースだと、変数の型に合うメソッドが呼び出されるな。
インターフェースの継承は、クラスの継承と同じ挙動だけど。
(Subclass#init(SubinterfaceA)は呼び出されない)

サンプルコード

public class OverloadIfTest {

    public static void main(String[] args) {
        new OverloadIfTest().test();
    }

    public void test() {
        System.out.println("\n■■■ OverloadIfTestの挙動 ■■■");
        new OverloadIfTest().setup();
        System.out.println("\n■■■ Subclassの挙動 ■■■");
        new Subclass().setup();
    }

    /* initメソッドの呼び出し元 */
    public void setup() {
        System.out.println("==== Subclass型の変数でinitを呼び出します ====");
        Subclass test = new Subclass();
        init(test);
        System.out.println("==== InterfaceA型の変数でinitを呼び出します ====");
        InterfaceA testA = new Subclass();
        init(testA);
        System.out.println("==== SubinterfaceA型の変数でinitを呼び出します ====");
        SubinterfaceA testSubA = new Subclass();
        init(testSubA);
        System.out.println("==== InterfaceB型の変数でinitを呼び出します ====");
        InterfaceB testB = new Subclass();
        init(testB);
    }

    /* Subclass型のinitメソッド */
    public void init(Subclass test) {
        System.out.println("OverloadIfTest#init(Subclass)です。");
    }

    /* InterfaceA型のinitメソッド */
    public void init(InterfaceA test) {
        System.out.println("OverloadIfTest#init(InterfaceA)です。");
    }

    /* InterfaceB型のinitメソッド */
    public void init(InterfaceB test) {
        System.out.println("OverloadIfTest#init(InterfaceB)です。");
    }

    /* OverloadIfTest を継承したクラス*/
    public class Subclass extends OverloadIfTest implements SubinterfaceA, InterfaceB {

        /* Subclass型のinitメソッドをオーバーライド */
        public void init(Subclass test) {
            System.out.println("Subclass#init(Subclass)です。");
        }

        /* InterfaceA型のinitメソッドはオーバーライドなし */

        /* SubinterfaceA型のinitメソッドをオーバーライド */
        public void init(SubinterfaceA test) {
            System.out.println("Subclass#init(SubinterfaceA)です。");
        }

        /* InterfaceB型のinitメソッドをオーバーライド */
        public void init(InterfaceB test) {
            System.out.println("Subclass#init(InterfaceB)です。");
        }
    }

    /* 各インターフェース */
    public interface InterfaceA { }
    public interface SubinterfaceA extends InterfaceA { }
    public interface InterfaceB { }

}

実行結果

■■■ OverloadIfTestの挙動 ■■■
==== Subclass型の変数でinitを呼び出します ====
OverloadIfTest#init(Subclass)です。
==== InterfaceA型の変数でinitを呼び出します ====
OverloadIfTest#init(InterfaceA)です。
==== SubinterfaceA型の変数でinitを呼び出します ====
OverloadIfTest#init(InterfaceA)です。
==== InterfaceB型の変数でinitを呼び出します ====
OverloadIfTest#init(InterfaceB)です。

■■■ Subclassの挙動 ■■■
==== Subclass型の変数でinitを呼び出します ====
Subclass#init(Subclass)です。
==== InterfaceA型の変数でinitを呼び出します ====
OverloadIfTest#init(InterfaceA)です。
==== SubinterfaceA型の変数でinitを呼び出します ====
OverloadIfTest#init(InterfaceA)です。
==== InterfaceB型の変数でinitを呼び出します ====
Subclass#init(InterfaceB)です。