接口中的default 方法(虚拟扩展方法、默认方法、守护方法)

default 关键字(虚拟扩展方法)

前言

也可称为Virtual extension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。

一、作用(为什么要有这个方法)

default关键字,成为虚拟扩展方法或者守护方法。


他的主要是作用是什么呢?你可以想想一个场景!

​ JDK7中有一个接口(我们暂且叫他InterfaceOne),然后有一系列的类实现了这个接口(这里叫这些类为ClassB)。他的子类又继承了ClassB(子类叫ClassC)。有一天,JDK的开发者们,想在InterfaceOne中加上一个抽象方法。但是,遇到了一个难题,这个难题是虽然在这个InterfaceOne接口中加上了这个方法,但是他的实现类(ClassB)、甚至他的实现类的子类(ClassC)都要实现这个方法。由此想象,这个工程量是不是巨大的。

​ 为了应对上述这个场景,在JDK8的时候引入了default扩展方法。以此达到可以做到JDK版本升级的时候,向某个接口添加抽象方法,其实现类不会受到任何影响,以达到在进行接口扩展时,不会破坏与接口相关的实现类的目的,做到向下兼容(向前兼容)。

二、具体代码示例

1.接口(小猫出生)

我们对于刚出生的小猫进行抽象,它会cry和对世界说helloWorld。

package defaultVitual;

public interface MyCat{
    public abstract void cry();
}

有一天,我们真的得到了一直小猫,这个小猫的叫声(cry)是“喵喵、喵喵”,对世界说helloWorld。这个它刚出生的时候(JDK7版本)

package defaultVitual;

/**
 * MyCat
 */
public class MyCatImplement implements MyCat{

    public static void main(String[] args) {
        MyCatImplement mycat = new MyCatImplement();
        //直接调用helloWorld()方法
        mycat.cry();
    }

    @Override
    public void cry() {
        System.out.println("我是小猫:我会喵喵、喵喵");
    }
}

执行结果:
在这里插入图片描述

2、向前兼容 (小猫长大啦)

长大后的小猫的抽象。它不仅会cry和对世界说helloWorld,还学会抓老鼠啦。我们要对这个小猫的抽象方法进行修改啦。

可以想象一下,如果我们直接在接口中再定义一个抽象方法。是不是我们的小猫实现类是不是也要跟着重写呢,如果是一个小猫还好说,如果出现很多个小猫接口的实现类呢,RedCat、BigCat,是否都要重写呢,是不是很麻烦呢。所以这个时候,我们使用default关键字。

package defaultVitual;

public interface MyCat{
    public abstract void cry();
    default void catchMouse() {
        System.out.println("我是小猫,我不仅会喵喵,我还会抓老鼠啦");
    }
}

长大后的小猫:

package defaultVitual;

/**
 * MyCat
 */
public class MyCatImplement implements MyCat{

    public static void main(String[] args) {
        MyCatImplement mycat = new MyCatImplement();
        //直接调用helloWorld()方法
        mycat.cry();
        mycat.catchMouse();
    }

    @Override
    public void cry() {
        System.out.println("我是小猫:我会喵喵、喵喵");
    }
}

运行结果:
在这里插入图片描述

通过这个样子,我们只需要修改小猫的接口,加上虚拟扩展方法,不再需要对小猫的实现类进行扩展。是不是省去了很大的工作量呢。

三、同时实现两个接口的相关方法名的default方法

public interface Interface1{
    default void helloWorld() {
        System.out.println("hi i'm from Interface1");
    }
}
————————————————————————————————————————————————————————————————————
public interface Interface2{
    default void helloWorld() {
        System.out.println("hi i'm from Interface2");
    }
}
——————————————————————————————————————————————————————————————————————
/**
 * 实现接口Interface1,Interface2
 */
public class MyImplement implements Interface1,Interface2{
    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        //直接调用helloWorld()方法
        myImplement.helloWorld();
    }
}

答案肯定无疑:编译器在检查的时候路就会出现报错。

在这里插入图片描述


具体如何解决这个问题呢?

当然就是在最新的实现类上重写这个default方法!!!又或者可以直接调用父类的接口中的默认方法!!!

  • 方式一:
package defaultVitual;

/**
 * 实现接口Interface1,Interface2
 */
public class MyImplement implements Interface1,Interface2{
    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        //直接调用helloWorld()方法
        myImplement.helloWorld();
    }

    @Override
    public void helloWorld() {
        Interface1.super.helloWorld();
    }
}
  • 方式二:
package defaultVitual;

/**
 * 实现接口Interface1,Interface2
 */
public class MyImplement implements Interface1,Interface2{
    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        //直接调用helloWorld()方法
        myImplement.helloWorld();
    }

    @Override
    public void helloWorld() {
        System.out.println("hi i'm from MyImplement");
    }
}

四、类优先于接口

当实现类同时继承了其他类,并且实现了接口,而其他类的方法和接口的默认方法都存在的时候 。

在这里插入图片描述

public class MyImplement2 extends MyImplement implements Interface2{
 
    public static void main(String[] args) {
        MyImplement2 myImplement2 = new MyImplement2();
        myImplement2.helloWorld();
    }
}

会优先执行于被继承的类的方法。

在这里插入图片描述

参考相关文章:

(如若有遗漏请联系我)


允许转载,若有侵权,将进行追究

若侵权他人,请联系我,进行删除,谢谢

来自一个写代码的小哥哥

若有错误,请联系我,进行修改


写代码,挣钱,努力,挣钱,run,run,run

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值