Default Methods实例解析

作者:星星的专栏 时间:2023-05-18 19:28:01 

Oracle官网是这样介绍默认方法的,使用默认方法,可以达到往接口里面增加新的功能,而且保持与老版本代码兼容,也就是原来的实现类可以不需要被动修改。所以,默认方法位置是在接口里面;默认方法具有实现,不会强制具体类来现。Java 8要充分利用Lambda,需要增强大量的类库,但是又希望做到兼容性,只能用默认方法这个大招。

默认方法

默认方法与普通的接口方法相比,最前面增加default关键字,参数列表之后接大括号,实现该方法,再后面没有分号。

如果翻看jdk源码的interface,会发现多了default关键词。

简单介绍下。

default使我们能够在不中断实现该接口的类的情况下向接口添加新的功能。 让我们来看看下面的例子。


public class MyClass implements InterfaceA {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
 // TODO code application logic here
}
@Override
public void saySomething() {
 System.out.println("Hello World");
}
}
interface InterfaceA {
public void saySomething();

}

上面的代码显示了类MyClass实现InterfaceA的方法saySomething()。 现在我们给InterfaceA添加一个名为sayHi()的新方法。 通过这样做,我们向类MyClass引入一个问题,因为它不会编译,直到我们提供方法sayHi()的实现。

这时Default就有用了。 通过在方法的访问修饰符之前添加关键字default,我们不必为类MyClass中的方法sayHi()提供实现。

在最严格的意义上,default是倒退一步,因为它们允许你用代码“污染”你的接口。 但它们提供了最优雅和实用的方式来允许向后兼容性。 它使jdk更容易更新所有Collections类,并为您改装现有的Lambda代码。(其实这就是default产生最初原因)


public class MyClass implements InterfaceA {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
 // TODO code application logic here
}
@Override
public void saySomething() {
 System.out.println("Hello World");
}
}
interface InterfaceA {
public void saySomething();
default public void sayHi() {
 System.out.println("Hi");
}
}

注意,我们必须提供所有default方法的实现。 因此,default方法为我们提供了在接口中实现方法的灵活性。 如果具体类不提供该方法的实现,那么实现将被用作默认值。

多接口冲突

由于java中的类可以实现多个接口,可能会有一个情况,其中两个或更多的接口有一个default方法具有相同的名称,因此导致冲突,因为java不知道一次使用什么方法。 这将导致编译错误:类MyClass从类型InterfaceA和InterfaceB继承default sayHi()
让我们来看看下面的例子。


public class MyClass implements InterfaceA, InterfaceB {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
 // TODO code application logic here
}
@Override
public void saySomething() {
 System.out.println("Hello World");
}
}
interface InterfaceA {

public void saySomething();

default public void sayHi() {
 System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB {
 default public void sayHi() {
 System.out.println("Hi from InterfaceB");
}
}

为了解决这样的情况,我们必须在类MyClass中提供sayHi()方法的实现,因此覆盖InterfaceA和InterfaceB中的两个方法。


public class MyClass implements InterfaceA, InterfaceB {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
 // TODO code application logic here
}
@Override
public void saySomething() {
 System.out.println("Hello World");
}
@Override
public void sayHi() {
 System.out.println("implemetation of sayHi() in MyClass");
}
}
interface InterfaceA {

public void saySomething();

default public void sayHi() {
 System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB {
 default public void sayHi() {
 System.out.println("Hi from InterfaceB");
}
}

如果我们想要在InterfaceA或InterfaceB中专门调用一个sayHi()方法,我们也可以这样做:


public class MyClass implements InterfaceA, InterfaceB {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
 // TODO code application logic here
}
@Override
public void saySomething() {
 System.out.println("Hello World");
}
@Override
public void sayHi() {
 InterfaceA.super.sayHi();
}
}

interface InterfaceA {

public void saySomething();

default public void sayHi() {
 System.out.println("Hi from InterfaceA");
}
}

interface InterfaceB {
 default public void sayHi() {
 System.out.println("Hi from InterfaceB");
}

来源:https://www.2cto.com/kf/201701/583676.html

标签:default,methods
0
投稿

猜你喜欢

  • Java接口返回json如何忽略特定属性

    2022-03-16 07:54:24
  • Java打印九九乘法表代码详情

    2022-03-14 17:42:14
  • springboot中使用Feign整合nacos,gateway进行微服务之间的调用方法

    2021-07-12 07:00:28
  • Android 实现自己的LOG信息

    2023-06-08 16:30:30
  • Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法

    2023-02-26 21:34:17
  • Java创建型设计模式之建造者模式详解

    2023-10-09 17:25:13
  • Spring与Shiro整合及加载权限表达式问题

    2023-10-01 09:29:50
  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    2021-07-12 04:16:10
  • JAVA通过HttpClient发送HTTP请求的方法示例

    2023-08-24 18:45:47
  • 解析Java和Eclipse中加载本地库(.dll文件)的详细说明

    2023-11-11 01:23:31
  • Android编程之selector下设置背景属性值的方法

    2023-08-23 08:07:49
  • Andoroid实现底部图片选择Dialog效果

    2022-11-11 22:41:03
  • IDEA 如何控制编辑左侧的功能图标ICON(操作步骤)

    2022-11-04 21:10:05
  • 详解通过JDBC进行简单的增删改查(以MySQL为例)

    2023-08-14 20:16:40
  • C#实现缩放和剪裁图片的方法示例

    2023-06-03 11:09:31
  • Unity UI实现拖拽旋转

    2023-04-10 06:44:59
  • 解决Intellij IDEA 使用Spring-boot-devTools无效的问题

    2023-09-17 20:49:47
  • 实例讲解Java中动态代理和反射机制

    2022-06-29 04:00:50
  • java中对象调用成员变量与成员实例方法

    2023-08-04 11:42:49
  • 教你安装配置Android Studio

    2023-07-09 03:26:17
  • asp之家 软件编程 m.aspxhome.com