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欢迎来留言啊!!!接口

相关文章
相关标签/搜索