java8新特性之接口中的默認方法與靜態方法

默認方法

Java 8中容許接口中包含具備具體實現的方法,該方法稱爲 「默認方法」,默認方法使用 default 關鍵字修飾。java

一個例子
/**
 * @author black貓
 * @date 2019-11-27
 * 一個接口
 */
public interface MyInterface<T> {

    /***
     * sayHi 抽象方法
     * @param name
     * @return
     */
    T sayHi(String name);

    /***
     * sayHello 默認方法
     * @param name
     * @return
     */
    default String sayHello(String name) {
        return "Hello :" + name;
    }
}

/**
 * @author black貓
 * @date 2019-11-28
 * 實現類
 */
public class MyInterfaceImpl implements MyInterface<String> {

    /***
     * sayHi 方法
     * @param name
     * @return
     */
    @Override
    public String sayHi(String name) {
        return "Hi :" +name;
    }
}

/***
 * @author black貓
 * @date 2019-11-27
 * 接口的實現類 測試
 */
public class MyInterfaceTest {
    /***
     * 測試默認方法
     */
    @Test
    public void test01() {
        MyInterface myInterface = new MyInterfaceImpl();
        // MyInterfaceImpl類並無實現 sayHello 方法就能夠調用 MyInterface接口的靜態方法
        System.out.println(myInterface.sayHello("Tom"));
        //  Hello :Tom
        System.out.println(myInterface.sayHi("Jim"));
        //  Hi :Jim
    }

}
默認方法的重寫,修改MyInterfaceImpl
/**
 * @author black貓
 * @date 2019-11-28
 * 實現類
 */
public class MyInterfaceImpl implements MyInterface<String> {

    /***
     * sayHi 方法
     * @param name
     * @return
     */
    @Override
    public String sayHi(String name) {
        return "Hi :" +name;
    }

    /***
     * sayHello 默認方法
     * @param name
     * @return
     */
    @Override
    public String sayHello(String name) {
        return "hello: "+name+" by MySuperClass...";
    }

}

/**
 * @author black貓
 * @date 2019-11-27
 * 接口的實現類 測試
 */
public class MyInterfaceTest {
    /***
     * 測試
     */
    @Test
    public void test01() {
        MyInterface myInterface = new MyInterfaceImpl();
        System.out.println(myInterface.sayHello("Tom"));
        //  hello: Tom by MySuperClass...
        System.out.println(myInterface.sayHi("Jim"));
        //  Hi :Jim
    }

}
默認方法的繼承

默認的方法也能夠被繼承ide

/**
 * @author black貓
 * @date 2019-11-27
 * 接口的實現類 測試
 */
public class MyInterfaceTest {

    @Test
    public void test02() {
         new Interface02(){}.printHello();
        //   Interface01 hello!
         new Interface03(){}.printHello();
        //   Interface03 hello!
         new Interface04(){
             @Override
             public void printHello() {
                 System.out.println("Interface04 hello!");
             }
         }.printHello();
        //   Interface04 hello!
    }
}
// Interface01接口裏面有一默認方法
interface Interface01 {
    default void printHello() {
        System.out.println("Interface01 hello!");
    }
}

/***
 * Interface02 繼承 Interface01 默認方法被繼承
 */
interface Interface02 extends Interface01 {
}


/***
 * Interface03 繼承 Interface01 默認方法繼承後重寫默認方法
 */
interface Interface03 extends Interface01 {
    @Override
    default void printHello() {
        System.out.println("Interface03 hello!");
    }
}

/***
 * Interface04 繼承 Interface01 默認方法繼承後從新定義爲抽象方法
 */
interface Interface04 extends Interface01 {
    @Override
    void printHello();
}
默認方法的多繼承

當接口的默認方法有衝突時,須要本身重寫調用方法,也能夠使用 InterfaceName.super.methodName(); 的方式手動調用須要的接口默認方法。測試

// Interface05接口有一個默認方法 printHello
interface Interface05 {
    default void printHello() {
        System.out.println("Interface05 hello!");
    }
}

// Interface06接口有一個默認方法 printHi
interface Interface06 {
    default void printHi() {
        System.out.println("Interface06 hi!");
    }
}

// Interface07接口有兩個默認方法 printHello 和 printHi
interface Interface07 {
    //默認方法 printHello
    default void printHello() {
        System.out.println("Interface07 hello!");
    }
    //默認方法 printHi
    default void printHi() {
        System.out.println("Interface07 hi!");
    }
}

// Class08 繼承 Interface05和Interface06
class Class08 implements Interface05, Interface06 {

}

// 報錯 Class09 繼承 Interface06和Interface07 
// 默認方法printHi衝突 必須選擇重寫一個父類的printHi
//class Class09 implements Interface06, Interface07 {
//
//}


// Class10 繼承 Interface06和Interface07
// 默認方法衝突 選擇一個重寫
class Class10 implements Interface06, Interface07 {
    @Override
    public void printHi() {
        //覆寫存在歧義的方法,能夠使用 InterfaceName.super.methodName(); 的方式手動調用須要的接口默認方法。
        Interface06.super.printHi();
        Interface07.super.printHi();
        System.out.println("Class10 hi!");
    }
}
接口和抽象類(類優先原則)

當接口繼承行爲發生衝突時,類的方法聲明優先於接口默認方法,不管該方法是具體的仍是抽象的。code

/**
 * @author black貓
 * @date 2019-11-28
 * 
 */
public class AbstractTest {

    public static void main(String[] args) {
        Class001 class001 = new Class001();
        class001.printHello();
        //  hello interface01...
        class001.printHi();
        //  hi abstract01...
    }

}

// 繼承抽象類Abstract001  而且實現接口Interface001
class Class001 extends Abstract001 implements Interface001 {

    @Override
    public void printHello() {
        Interface001.super.printHello();
    }

}

// 一個接口有兩個默認方法
interface Interface001 {
    default void printHello() {
        System.out.println("hello interface01...");
    }

    default void printHi() {
        System.out.println("hi interface01...");
    }
}

//一個抽象類 有一個抽象方法 一個實現的方法
abstract class Abstract001 {

    abstract void printHello();

    public void printHi() {
        System.out.println("hi abstract01...");
    }
}
接口的靜態方法

接口的靜態方法和類的靜態方法使用一致繼承

/**
 * @author black貓
 * @date 2019-11-28
 * Java 8 還在容許在接口中定義靜態方法。
 */
public class StaticTest {

    public static void main(String[] args) {
        Interface.printHelloWorld();
    }

}

/**
 * Interface接口有一個靜態方法 printHelloWorld
 */
interface Interface {
    /***
     * 靜態方法
     */
    static void printHelloWorld() {
        System.out.println("Interface11 printHelloWorld...");
    }

}

個人小結

java8的接口默認方法下降了實現類之間的耦合,當須要爲一個接口添加方法時,沒必要對全部實現類都修改。能夠爲接口添加新的默認方法,而不會破壞已有的接口的實現,也爲升級舊接口且保持向後兼容提供了新的途徑。

文章首發於黑貓のBlog歡迎來留言啊!!!接口

相關文章
相關標籤/搜索