Java8中接口的新特性测试

所属分类: 软件编程 / java 阅读数: 38
收藏 0 赞 0 分享

在Java SE 8之前,接口中是不能提供方法实现的,但是JDK8提供了接口的默认方法和静态方法的支持。

默认方法

方法前加default关键字就可以提供默认实现,类实现接口时,可以继承接口的默认方法,也可以覆盖默认方法。

interface People {
  default void eat(String name) {
    System.out.println(name + " is eating.");
  }
}

抽象类也可以提供方法的默认实现,一个类可以同时继承一个抽象类和多个接口,如果抽象类和接口中存在相同的方法时会怎么样呢?

一个抽象类和多个接口

如果类继承了抽象类,采取类优先的原则,优先继承抽象类的方法。我们在编写类的时候会发现,必须先extends类再implements接口,否则工具会提示extends的错误。不论抽象类的方法有没有提供默认实现,类都会继承抽象类的方法,就算接口的方法提供了默认实现,也完全不关心。

接口A,B:

interface A {
  default void eat() {
    System.out.println("A");
  }
}
interface B {
  default void eat() {
    System.out.println("B");
  }
}

抽象类C:

abstract class C {
  public void eat() {
    System.out.println("C");
  }
}

测试类Test:

public class Test extends C implements A, B {
 public static void main(String[] args) {
    Test test = new Java8Test();
    test.eat();
  }
}

输出结果:

C

程序输出C说明Test类继承了抽象类C的eat方法的实现。

当抽象类C不提供eat方法的默认实现并且Test类不提供eat方法的重写时,编译器是不会放过Test类的,明明继承了C类,却不提供抽象方法的实现。编译器不会关心Test是否还实现了其他接口并且接口中有相同方法,一码归一码。

那么如果是抽象类提供了默认实现,接口没有提供呢?

我们让抽象类C实现eat方法,接口A只提供一个接口,类Test不重写eat方法。

接口A,B:

interface A {
  void eat();
}
interface B {
  default void eat() {
    System.out.println("B");
  }
}

抽象类C:

abstract class C {
  public void eat() {
    System.out.println("C");
  }
}

测试类Test:

public class Test extends C implements A, B {
 public static void main(String[] args) {
    Test test = new Test();
    test.eat();
  }
}

运行main方法,控制台打印出抽象类中eat方法的输出结果。

其实我们可以这么理解,编译器总要一步一步的编译,首先编译到extends,检查所有的抽象方法是否被重写,有没被重写的方法就抛出编译错误,否则就继续编译。当编译到implements时,类Test已经是拥有抽象类C所有方法的实现了,即已经提供了接口A和B中相同方法的重写。

以上总结就是抽象类和接口的方法冲突时以抽象类为准就是了。如果抽象类不在了,两个接口方法冲突了,该听谁的呢?

多个接口

接口A提供方法默认实现,接口B只提供方法。

接口A、B:

interface A {
   default void eat() {
     System.out.println("A");
   }
}
interface B {
  default void eat() {
     System.out.println("B");
   }
}

测试类Test:

public class Test implements A, B {
  public static void main(String[] args) {
    Test test = new Test();
    test.eat();
  }
}

此时编译器提示,类Test从类型A和B中继承了eat()的不相关默认值。也就是说,当两个接口冲突时,编译器无法判断继承A还是继承B的方法实现。这时候,类Test就需要自己提供eat()方法的实现了。

静态方法

接口中也可以提供静态方法,使用static关键字。类不能继承接口的静态方法,所以也不存在覆盖静态方法。访问静态方法时通过接口访问,即People.eat(“name”)。

interface People {
  static void eat(String name) {
    System.out.println(name + " is eating.");
  }
}

可以测试一下,调用继承了People接口的类实例的eat方法,工具提示不能通过类实例访问静态成员。或者试着重写一个eat方法并加上@Override注解,工具提示“Method does not override method from its superclass”。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

更多精彩内容其他人还在看

java实现背单词程序

这篇文章主要为大家详细介绍了java实现背单词程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java实现单词查询小程序

这篇文章主要为大家详细介绍了java实现单词查询小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java程序开发环境配置图文教程

这篇文章主要为大家详细介绍了Java程序开发环境配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解ssh框架原理及流程

在本文中小编给大家整理的是关于ssh框架原理及流程的相关知识点内容,有此需要的朋友们可以学习下。
收藏 0 赞 0 分享

Java实现弹窗效果的基本操作

这篇文章主要为大家详细介绍了Java实现弹窗效果的基本操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解springmvc常用5种注解

在本篇里我们给大家总结了关于springmvc常用5种注解相关知识点以及实例代码,需要的朋友们参考下。
收藏 0 赞 0 分享

Java实现弹窗效果的基本操作(2)

这篇文章主要为大家详细介绍了Java实现弹窗效果的基本操作第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Spring Boot假死诊断实战记录

这篇文章主要给大家介绍了关于Spring Boot假死诊断的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Java计时新姿势StopWatch详解

这篇文章主要介绍了Java计时新姿势StopWatch,最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时的新姿势「StopWatch」,需要的朋友可以参考下
收藏 0 赞 0 分享

java实现点击按钮弹出新窗体功能

这篇文章主要为大家详细介绍了java实现点击按钮弹出新窗体功能,旧窗体不进行操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多