JDK8中接口的变化

JDK8中接口的变化

文字描述

  • JDK8中,接口中可以定义default方法和static方法。
    1. 接口中的 default方法 只能使用接口的实现类对象来调用(default方法属于实例)。
    2. 接口中的 static方法 只能使用“接口名.静态方法名” 的方式调用(static方法属于接口)。
    3. 接口中的静态方法不会被子接口继承,
      接口中的静态变量被子接口继承,
      接口中的默认方法被子接口继承。
    4. 实现类可以重写接口中的默认方法(IDEA中按ctrl+o重写方法)。如果一个类实现了多个接口,并且这些接口中有相同的默认方法,并且这些接口之间没有继承关系,那么这个实现类必须重写这个重名的默认方法。能通过特殊的语法在重写的方法中指定要调用哪个接口中的默认方法。
      这个特殊的语法是:<接口名>.super.<方法名>([参数])
    5. 和上述的第4条类似。
      子接口可以重写父接口中的默认方法(IDEA中按ctrl+o重写方法)。如果一个接口继承了多个接口,并且这些接口中有相同的默认方法,并且这些接口之间没有继承关系,那么这个接口必须重写这个重名的默认方法。能通过特殊的语法在重写的方法中指定要调用哪个接口中的默认方法。
      这个特殊的语法是:<接口名>.super.<方法名>.([参数])
    6. 自从接口里面可以有静态方法,从此接口中可以写main方法, 可以作为程序的入口,但是一般不这么做。
    7. 在子接口中能使用默认方法来实现父接口中的抽象方法。这样子接口的实现类中就不需要再实现这个抽象方法了,如果实现类再去实现子接口中的默认方法,那么相当于是 “方法重写”,即重写了子接口中的这个默认方法。
    8. 如果一个接口中只有一个抽象方法(包括继承来的抽象方法),那么这个接口叫做函数式接口,函数式接口能和Lambda表达式配合使用。@FunctionalInterface注解标注在接口上,作用就是告诉编译器该接口中只能有一个抽象方法. 包括继承父接口中的抽象方法和接口本身定义的抽象方法, 总共不能超过1个。
    9. 没有任何方法的接口通常用于标记使用。
      例如用于声明某类的实例可以被序列化的接口java.io.Serializable

代码演示

  • 对应上述的 1、2。
package cn.king.demo01;

/**
 * 接口
 */
interface MyInter01 {
    // 接口中的 default方法 只能被接口的实现类对象调用
    default void fun1() {
        System.out.println("接口MyInter01中的default方法被调用");
    }

    // 接口中的 static方法 只能使用“接口名.静态方法名”的方式调用
    static void fun2() {
        System.out.println("接口MyInter01中的static方法被调用");
    }
}

/**
 * 实现类
 */
class MyInter01Impl implements MyInter01 {

}

/**
 * 测试
 */
public class Demo01 {
    public static void main(String[] args) {
        MyInter01Impl myInter01 = new MyInter01Impl();
        /*
         * 接口中的 default方法 只能被接口的实现类对象调用
         */
        // 下句输出:接口MyInter01中的default方法被调用
        myInter01.fun1();

        /*
         * 接口中的 static方法 只能使用“接口名.静态方法名”的方式调用
         */
        // 下句输出:接口MyInter01中的static方法被调用
        MyInter01.fun2();

        /*
         * 接口中的 static方法 只能使用“接口名.静态方法名”的方式调用.
         */
        // 下句报错。不能用实现类随想来调用接口中的静态方法。
        //myInter01.fun2();
    }
}
  • 对应上述的3。
package cn.king.demo01;

/**
 * 接口1
 */
interface MyInter01 {
    // 子父接口中同名的静态变量
    public static String s1 = "MyInter01中的s1";
    // 父接口中独有的静态变量
    public static String s100 = "s100";
}

/**
 * 接口2
 */
interface MyInter02 extends MyInter01 {
    // 子父接口中同名的静态变量
    public static String s1 = "MyInter02中的s1";
    // 子接口中独有的静态变量
    public static String s200 = "s200";
}

/**
 * 测试
 */
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(MyInter01.s1); // MyInter01中的s1
        System.out.println(MyInter01.s100); // s100

        // 接口的静态变量会被子接口继承
        System.out.println(MyInter02.s1); // MyInter02中的s1
        System.out.println(MyInter02.s100); // s100
        System.out.println(MyInter02.s200); // s200
    }
}
package cn.king.demo01;

/**
 * 接口1
 */
interface MyInter01 {
    default void fun1() {
        System.out.println("接口MyInter01的默认方法fun1()");
    }
}

/**
 * 接口2
 */
interface MyInter02 extends MyInter01 {
    default void fun2() {
        System.out.println("接口MyInter02的默认方法fun2()");
    }
}

/**
 * 接口2的实现类
 */
class MyInter02Impl implements MyInter02 {

}

/**
 * 测试
 */
public class Demo01 {
    public static void main(String[] args) {
        // 接口的默认方法会被子接口继承
        MyInter02Impl myInter02 = new MyInter02Impl();
        myInter02.fun1(); // 接口MyInter01的默认方法fun1()
        myInter02.fun2(); // 接口MyInter02的默认方法fun2()
    }
}
  • 对应上述4。
package cn.king.demo01;

/**
 * 接口1
 */
interface MyInter01 {
    // 接口MyInter01和接口MyInter02中有同名的default方法fun1()
    default void fun1() {
        System.out.println("接口MyInter01的默认方法fun1()");
    }
}

/**
 * 接口2
 */
interface MyInter02 {
    // 接口MyInter01和接口MyInter02中有同名的default方法fun1()
    default void fun1() {
        System.out.println("接口MyInter02的默认方法fun1()");
    }
}

/**
 * 接口1 和 接口2 的实现类
 */
class MyInterImpl implements MyInter01, MyInter02 {
    @Override
    public void fun1() {
        //MyInter01.super.fun1();
        MyInter02.super.fun1();
    }
}

/**
 * 测试
 */
public class Demo01 {
    public static void main(String[] args) {
        MyInterImpl myInter = new MyInterImpl();

        //myInter.fun1(); // 接口MyInter01的默认方法fun1()
        myInter.fun1(); // 接口MyInter02的默认方法fun1()
    }
}
  • 对应上述的5。
package cn.king.demo01;

/**
 * 接口1
 */
interface MyInter01 {
    // 接口MyInter01和接口MyInter02中有同名的default方法fun1()
    default void fun1() {
        System.out.println("接口MyInter01的默认方法fun1()");
    }
}

/**
 * 接口2
 */
interface MyInter02 {
    // 接口MyInter01和接口MyInter02中有同名的default方法fun1()
    default void fun1() {
        System.out.println("接口MyInter02的默认方法fun1()");
    }
}

/**
 * 接口1 和 接口2 的子接口
 */
interface MyInter extends MyInter01, MyInter02 {
    @Override
    default void fun1() {
        //MyInter02.super.fun1();
        MyInter01.super.fun1();
    }
}

/**
 * MyInter接口的实现类
 */
class MyInterImpl implements MyInter {

}

/**
 * 测试
 */
public class Demo01 {
    public static void main(String[] args) {
        MyInterImpl myInter = new MyInterImpl();
        
        //myInter.fun1(); // 接口MyInter02的默认方法fun1()
        myInter.fun1(); // 接口MyInter01的默认方法fun1()
    }
}
  • 对应上述的7。
package cn.king.demo01;

/**
 * 接口1
 */
interface MyInter01 {
    public abstract void fun1();
}


/**
 * 接口1的子接口
 */
interface MyInter extends MyInter01 {
    // 使用default方法实现了父接口MyInter01中的抽象方法fun1()
    @Override
    default void fun1() {
        System.out.println("MyInter中的default方法fun1()");
    }
}

/**
 * 接口1的子接口的实现类
 */
class MyInterImpl implements MyInter {
    // 重写了接口MyInter中的fun1()方法
    @Override
    public void fun1() {
        System.out.println("MyInterImpl中的方法fun1()");
    }
}

jdk8以前接口的特点见我的另一篇博客:抽象类与接口的区别&抽象类中构造方法的作用(super关键词调用父类构造方法的作用)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值