Java8接口之默认方法与静态方法详解

 更新时间:2022年03月30日 08:23:28   作者:老K的Java博客  
java8中为接口新增了一项功能,定义一个或者更多个静态方法,类似于类中的静态方法,接口定义的静态方法可以独立于任何对象调用,下面这篇文章主要给大家介绍了关于Java8接口之默认方法与静态方法的相关资料,需要的朋友可以参考下

前言

在Java8之前,java中的接口只能有抽象方法。默认情况下,接口的所有方法都是公共和抽象的。Java8允许接口具有默认和静态方法。我们在接口中使用默认方法的原因是,允许开发人员向接口添加新方法,而不会影响实现这些接口的类。

为什么选择默认方法?

例如,如果A、B、C和D等几个类实现了一个接口XYZInterface,那么如果我们向XYZInterface添加一个新方法,我们必须更改实现该接口的所有类(A、B、C和D)中的代码。在本例中,我们只有四个类实现了我们想要更改的接口,但是想象一下,如果有数百个类实现了一个接口,那么几乎不可能更改所有这些类中的代码。这就是为什么在Java8中,我们有了一个新概念“默认方法”。这些方法可以添加到任何现有接口中,我们不需要强制在实现类中实现这些方法,因此我们可以在不破坏代码的情况下将这些默认方法添加到现有接口中。

我们可以说,java 8中引入了默认方法的概念,以便在现有接口中添加新方法,从而使它们向后兼容。向后兼容性是在不破坏旧代码的情况下添加新功能。

接口中的静态方法与默认方法类似,只是我们不能在实现这些接口的类中重写这些方法。

Java 8示例:接口中的默认方法

MyInterface中的方法newMethod()是默认方法,这意味着我们不需要在实现类示例中实现该方法。通过这种方式,我们可以将默认方法添加到现有接口中,而不必担心实现这些接口的类。

interface MyInterface{  
    /* This is a default method so we need not
     * to implement this method in the implementation 
     * classes  
     */
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    /* Already existing public and abstract method
     * We must need to implement this method in 
     * implementation classes.
     */
    void existingMethod(String str);  
}  
public class Example implements MyInterface{ 
    // implementing abstract method
    public void existingMethod(String str){           
        System.out.println("String is: "+str);  
    }  
    public static void main(String[] args) {  
        Example obj = new Example();
        
        //calling the default method of interface
        obj.newMethod();     
        //calling the abstract method of interface
        obj.existingMethod("Java 8 is easy to learn"); 
  
    }  
}

输出:

Newly added default method
String is: Java 8 is easy to learn

Java 8示例:接口中的静态方法

如上所述,接口中的静态方法与默认方法类似,因此我们不需要在实现类中实现它们。我们可以安全地将它们添加到现有接口中,而无需更改实现类中的代码。由于这些方法是静态的,我们不能在实现类中重写它们。

interface MyInterface{  
    /* This is a default method so we need not
     * to implement this method in the implementation 
     * classes  
     */
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    
    /* This is a static method. Static method in interface is
     * similar to default method except that we cannot override 
     * them in the implementation classes.
     * Similar to default methods, we need to implement these methods
     * in implementation classes so we can safely add them to the 
     * existing interfaces.
     */
    static void anotherNewMethod(){
        System.out.println("Newly added static method");
    }
    /* Already existing public and abstract method
     * We must need to implement this method in 
     * implementation classes.
     */
    void existingMethod(String str);  
}  
public class Example implements MyInterface{ 
    // implementing abstract method
    public void existingMethod(String str){           
        System.out.println("String is: "+str);  
    }  
    public static void main(String[] args) {  
        Example obj = new Example();
        
        //calling the default method of interface
        obj.newMethod();     
        //calling the static method of interface
        MyInterface.anotherNewMethod();
        //calling the abstract method of interface
        obj.existingMethod("Java 8 is easy to learn"); 
    }  
}

输出:

Newly added default method
Newly added static method
String is: Java 8 is easy to learn

Java 8 - 抽象类与接口

随着接口中默认方法的引入,抽象类似乎与Java8中的接口相同。然而,这并不是完全正确的,尽管我们现在可以像抽象类一样在接口中有具体的方法(带主体的方法),但这并不意味着它们是相同的。它们之间仍然没有什么区别,其中之一是抽象类可以有构造函数,而在接口中我们不能有构造函数。

接口的目的是提供完全抽象,而抽象类的目的是提供部分抽象。这仍然适用。界面就像是类的蓝图,通过引入默认方法,您可以简单地说,我们可以在界面中添加附加功能,而不会影响最终用户类。

默认方法和多重继承

当我们有两个具有相同签名的默认方法的接口时,可能会出现多重继承问题。让我们举个例子。

interface MyInterface{  
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    void existingMethod(String str);  
}  
interface MyInterface2{  
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    void disp(String str);  
} 
public class Example implements MyInterface, MyInterface2{ 
    // implementing abstract methods
    public void existingMethod(String str){           
        System.out.println("String is: "+str);  
    }  
    public void disp(String str){
        System.out.println("String is: "+str); 
    }
    
    public static void main(String[] args) {  
        Example obj = new Example();
        //calling the default method of interface
        obj.newMethod();     
    }  
}

输出:

Error: Duplicate default methods named newMethod with the parameters () and () are inherited from the types MyInterface2 and MyInterface

这是因为我们在接口中都有相同的方法,而编译器不确定要调用哪个方法。

如何解决这个问题?

为了解决这个问题,我们可以在实现类中实现这个方法,如下所示:

interface MyInterface{  
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    void existingMethod(String str);  
}  
interface MyInterface2{  
     
    default void newMethod(){  
        System.out.println("Newly added default method");  
    }  
    void disp(String str);  
} 
public class Example implements MyInterface, MyInterface2{ 
    // implementing abstract methods
    public void existingMethod(String str){           
        System.out.println("String is: "+str);  
    }  
    public void disp(String str){
        System.out.println("String is: "+str); 
    }
    //Implementation of duplicate default method
    public void newMethod(){  
        System.out.println("Implementation of default method");  
    }  
    public static void main(String[] args) {  
        Example obj = new Example();
        //calling the default method of interface
        obj.newMethod();     
    }  
}

输出:

Implementation of default method

首先我们要总体说一下,为什么要有这两个方法存在:

(1)原先的jdk7之类的,它们接口中的方法都是抽象方法,没有具体的实现,就相当于定义好了这个接口有哪些功能,却没有具体定义功能是怎么实现的,通常由接口的实现类来做具体功能实现。那么,如果面向接口编程,大家已经根据自己需要通过继承接口的方式来实现了自己的功能,突然有一天,产品提需求了,你需要给所有接口的实现类都添加一个新的功能即一个新的方法实现,而且这个方法可能大家都是一样的,那咋办?

jdk8以前的做法肯定是现在接口中定义这个抽象方法,然后所有实现类必须实现这个方法(不然接口中多出一个抽象方法,其他类都没有实现,编译是会报错的),如果实现类比较多,那改起来会很麻烦,这种情况下是不利于维护的。

那么我们在jdk8中就有了好的解决方式,就是在接口中加一个默认方法,这个默认方法有具体实现,这样就不用去修改实现类啦,很省事。

总结

到此这篇关于Java8接口之默认方法与静态方法的文章就介绍到这了,更多相关Java8默认方法与静态方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Eclipse配置SVN的几种方法及使用详情

    Eclipse配置SVN的几种方法及使用详情

    这篇文章主要介绍了Eclipse配置SVN的几种方法及使用详情,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • SpringBoot任务调度器的实现代码

    SpringBoot任务调度器的实现代码

    SpringBoot自带了任务调度器,通过注解的方式使用。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • SpringBoot的@EnableAsync和@Async注解分析

    SpringBoot的@EnableAsync和@Async注解分析

    这篇文章主要介绍了SpringBoot的@EnableAsync和@Async注解分析,Spring Boot是一个快速开发框架,可以帮助开发人员快速构建基于Spring的应用程序,需要的朋友可以参考下
    2023-07-07
  • Java Ribbon与openfeign区别和用法讲解

    Java Ribbon与openfeign区别和用法讲解

    Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具,主要功能是提供客户端的软件负载均衡算法和服务调用。openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便
    2022-08-08
  • MyBatis 如何使项目兼容多种数据库的解决方案

    MyBatis 如何使项目兼容多种数据库的解决方案

    要想做兼容多种数据库,那毫无疑问,我们首先得明确我们要兼容哪些数据库,他们的数据库产品名称是什么,本次我们讲解了一套使项目兼容多种数据库的方案,对MyBatis项目兼容多种数据库操作方法感兴趣的朋友一起看看吧
    2024-05-05
  • Java使用TCP套接字实现多人聊天功能详解

    Java使用TCP套接字实现多人聊天功能详解

    这篇文章主要介绍了Java使用TCP套接字实现多人聊天功能,结合实例形式详细分析了java使用socket通信实现tcp协议下的聊天功能客户端与服务器端相关实现技巧,需要的朋友可以参考下
    2019-10-10
  • SpringBoot如何读取application.properties配置文件

    SpringBoot如何读取application.properties配置文件

    这篇文章主要介绍了SpringBoot如何读取application.properties配置文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Java ConcurrentHashMap用法案例详解

    Java ConcurrentHashMap用法案例详解

    这篇文章主要介绍了Java ConcurrentHashMap用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Java实现MD5加密及解密的代码实例分享

    Java实现MD5加密及解密的代码实例分享

    如果对安全性的需求不是太高,MD5仍是使用非常方便和普及的加密方式,比如Java中自带的MessageDigest类就提供了支持,这里就为大家带来Java实现MD5加密及解密的代码实例分享:
    2016-06-06
  • JAVA核心知识之ConcurrentHashMap源码分析

    JAVA核心知识之ConcurrentHashMap源码分析

    这篇文章主要介绍了JAVA核心知识之ConcurrentHashMap源码分析,想了解ConcurrentHashMap的同学一定要看啊
    2021-04-04

最新评论