接口的新特性

接口的新特性

Java SE7以前:

接口只能有常量和抽象方法,只能通过实现接口来对相关方法进行操作。

interface 接口名{
	全局常量;
	抽象方法;
}

Java8:

可以在接口中编写方法实现。支持以下定义:

  • 常量

  • 抽象方法

  • 默认方法

  • 静态方法

    public interface A {
        String a="a";
        /**正常定义一个抽象方法*/
        public void method();
        /**使用default 来申明一个默认实现方法*/
        default void method1(){
            System.out.println("I'm default method in Interface A!");
        }
        /** 使用static 来申明一个静态实现方法*/
        static void method2(){
            System.out.println("I'm default method in Interface A!");
        }
    }
    

静态方法的使用

直接用接口名.方法名就可以使用。

默认方法的使用

默认方法在实现类中可以直接使用 :

public class TestDemo1 implements A{
    public static void main(String[] args) {
        TestDemo1 td = new TestDemo1();
        //抽象方法必须实现才能使用
        td.method();
        //默认方法可以直接使用
        td.method1();
        //静态方法必须通过接口名.方法名使用
        A.method2();
    }
    @Override
    public void method() {
        System.out.println("override method of Interface A!");
    }
}

如果在某个时候我们往接口添加更多的默认方法,实现类可以不用修改继续使用

默认方法的最典型用法是逐步为接口提供附加功能,而不破坏实现类。

此外,它们还可以用来为现有的抽象方法提供额外的功能:

interface MobilePhone {
    /**
     * 获取手机长度(毫米)
     */
    Double getLength();

    /**
     * 对getLength方法进行拓展,返回厘米为单位的长度
     */
    default String getLengthInCm() {
        return getLength() / 10 + "cm";
    }
}

默认方法的多继承

当一个类继承多个接口时如果接口中有同方法标签的方法必须重写,否则会报错。

public interface A {
    /**使用default 来申明一个默认实现方法*/
    default void method1(){
        System.out.println("I'm default method in Interface A!");
    }
}

public interface A {
    /**使用default 来申明一个默认实现方法*/
    default void method1(){
        System.out.println("I'm default method in Interface B!");
    }
}

public class TestDemo2 implements A,B{
    @Override
    public void method1() {
        System.out.println("我是重写的method1!");
    }
}

由于类可以实现多个接口,也可以继承类,当接口或类中有相同函数签名的方法时,这个时候到底使用哪个类或接口的实现呢?这里有三个规则可以进行判断:

  • 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
public interface A {
    /**使用default 来申明一个默认实现方法*/
    default void method1(){
        System.out.println("I'm default method in Interface A!");
    }
}

public class C {
	/**类C中同方法标签的method1*/
    public void method1(){
        System.out.println("I'm method1 in Class C!");
    }
}

public class TestDemo3 extends C implements A{
    public static void main(String[] args) {
        TestDemo3 td = new TestDemo3();
        td.method1();
    }
}

结果:I'm method1 in Class C!

  • 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果接口B继承了接口A,那么B就比A更加具体。
public interface A {
    /**使用default 来申明一个默认实现方法*/
    default void method1(){
        System.out.println("I'm default method in Interface A!");
    }
}

public interface D extends A{
    /**使用default 来申明一个默认实现方法*/
    @Override
    default void method1(){
        System.out.println("I'm default method in Interface D!");
    }
}

/**TestDemo4实现接口A和D,接口D继承了接口A*/
public class TestDemo4 implements A,D{
    public static void main(String[] args) {
        TestDemo4 td = new TestDemo4();
        td.method1();
    }
}

结果:I'm default method in Interface D!

  • 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。不然编译都会报错。 (其实就是最开始说的接口默认方法的多继承)
public class TestDemo5 implements A,B{
    public static void main(String[] args) {
        TestDemo5 td = new TestDemo5();
        td.method1();
    }
    @Override
    public void method1() {
        A.super.method1();
        //B.super.method1();
    }
}

结果:I'm default method in Interface A!

java 9

接口支持以下定义:

  • 常量
  • 抽象方法
  • 默认方法
  • 静态方法
  • 私有方法
  • 私有静态方法
 public interface JavaNine{
      String TYPE_NAME = "java seven interface";
      int TYPE_AGE = 20;
      String TYPE_DES = "java seven interface description";

      default void method01(){
      
      }
      default void method02(String message){
       
      }

      private void method(){
      		//在这里,我们将冗余代码提取到通用的私有方法中,以便我们的API客户端无法看到它们。
         
      }

      // 其他抽象方法
      void method03();
      void method04(String arg);
      ...
      String method05();
   }

在Interface中编写私有方法时,我们应该遵循以下规则:

  • 我们应该使用私有修饰符(private)来定义这些方法。
  • 我们不能同时使用私有修饰符(private)和abstract来定义这些方法。
    • “私有”方法意味着完全实现的方法,因为子类不能继承并覆盖此方法。
    • “抽象”方法意味着无实现方法。这里子类应该继承并覆盖此方法。
  • 私有方法必须包含方法体,必须是具体方法。
  • 这些接口私有方法仅在该接口内是有用的或可访问的。我们无法从接口访问或继承私有方法到另一个接口或类。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值