欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

30分钟入门Java8之默认方法和静态接口方法学习

程序员文章站 2024-03-02 21:55:04
前言 上一篇文章30分钟入门java8之lambda表达式,我们学习了lambda表达式。现在继续java8新语言特性的学习,今天,我们要学习的是默认方法和静态接口方法。...

前言

上一篇文章30分钟入门java8之lambda表达式,我们学习了lambda表达式。现在继续java8新语言特性的学习,今天,我们要学习的是默认方法和静态接口方法。

这一java8的新语言特性,在android n中也得到了支持。至于如何在android开发中配置java8的开发环境,请查看上一篇文章30分钟入门java8之lambda表达式。

默认方法

默认方法让我们能给我们的软件库的接口增加新的方法,并且能保证对使用这个接口的老版本代码的兼容性。

下面通过一个简单的例子来深入理解下默认方法:

1.一天,pm说我们的产品需要获取时间和日期。于是我们就写了一个设置和获取日期时间的接口类 timeclient 。

 public  interface  timeclient { 

    void settime(int hour,int  minute,  int  second); 

    void  setdate( int  day,  int  month,  int  year); 

    void  setdateandtime( int  day,  int  month,  int  year, 

              int  hour,  int  minute,  int  second); 

    localdatetime getlocaldatetime(); 

 } 

以及这个接口的实现类 simpletimeclient :

public  class  simpletimeclient  implements  timeclient {

    private  localdatetime localdatetime;

    public  simpletimeclient(){ 

      localdatetime = localdatetime.now(); 

    } 

    @override 

    public  void  settime( int  hour,  int  minute,  int  second) { 

      localtime localtime = localtime.of(hour, minute, second); 

      localdate localdate = localdate.from(localdatetime); 

      localdatetime = localdatetime.of(localdate,localtime); 

    } 

 

    @override 

    public  void  setdate( int  day,  int  month,  int  year) { 

      localdate localdate = localdate.of(day, month, year); 

      localtime localtime = localtime.from(localdatetime); 

      localdatetime = localdatetime.of(localdate, localtime); 

    } 

 

    @override 

    public  void  setdateandtime( int  day,  int  month,  int  year,  int  hour,  int  minute,  int  second) { 

      localdate localdate = localdate.of(day, month, year); 

      localtime localtime = localtime.of(hour, minute, second); 

      localdatetime = localdatetime.of(localdate, localtime); 

    } 

 

    @override 

    public  localdatetime getlocaldatetime() { 

      return  localdatetime; 

    } 

 

    @override 

    public  string tostring() { 

      return  localdatetime.tostring(); 

    } 

 

    public  static  void  main(string[] args) { 

      timeclient timeclient =  new  simpletimeclient(); 

      system.out.println(timeclient.tostring()); 

    } 

 } 

2.可是pm说我们这个产品呐,不光国内用,各种其他时区的顾客也会使用。于是给你增加了新的需求:获取指定时区的日期和时间

以往我们都会这么做:

重写接口,增加方法

 public interface timeclient { 

    void settime(int hour,int minute,int second); 

    void setdate(int day,int month,int year); 

    void setdateandtime(int day,int month,int year,int hour, int minute,int second); 

    localdatetime getlocaldatetime(); 

    //新增的方法              

    zoneddatetime getzoneddatetime(string zonestring); 

 }

这样我们的实现类也要相应的进行重写。

 public  class  simpletimeclient  implements  timeclient {

    private  localdatetime localdatetime; 

    ... 

    zoneddatetime getzoneddatetime(string zonestring){ 

     return  zoneddatetime.of(getlocaldatetime(), getzoneid(zonestring)); 

    }    

    static  zoneid getzoneid (string zonestring) { 

      try  { 

        return  zoneid.of(zonestring); 

      }  catch  (datetimeexception e) { 

        system.err.println( "invalid time zone: "  + zonestring + 

          "; using default time zone instead." ); 

        return  zoneid.systemdefault(); 

      } 

    }   

  } 

这样写会导致我们要去重写每个实现了 timeclient 接口的类。而这大大增加了我们的实现需求的负担。

正是为了解决java接口中只能定义抽象方法的问题。java8新增加了默认方法的特性。下面让我们来使用默认方法实现需求。

 public  interface  timeclient { 

    void  settime( int  hour,  int  minute,  int  second); 

    void  setdate( int  day,  int  month,  int  year); 

    void  setdateandtime( int  day,  int  month,  int  year, 

      int  hour,  int  minute,  int  second); 

    localdatetime getlocaldatetime();              

    static  zoneid getzoneid (string zonestring) { 

      try  { 

        return  zoneid.of(zonestring); 

      }  catch  (datetimeexception e) { 

        system.err.println( "invalid time zone: "  + zonestring + 

          "; using default time zone instead." ); 

        return  zoneid.systemdefault(); 

      } 

    } 

    //默认方法 

    default  zoneddatetime getzoneddatetime(string zonestring) { 

      return  zoneddatetime.of(getlocaldatetime(), getzoneid(zonestring)); 

    } 

 } 

默认方法关键字为 default ,以往我们只能在接口中定义只有声明没有实现的方法。有了默认方法,我们就能编写完整的方法。

这样我们就不需要修改继承接口的实现类,就给接口添加了新的方法实现。

 public  static  void  main(string[] args) { 

      timeclient timeclient =  new  simpletimeclient(); 

      system.out.println(timeclient.tostring()); 

      system.out.println(timeclient.getzoneddatetime( "test" )); 

    } 

继承含有默认方法的接口

当我们继承含有默认方法的接口时,一般有以下三种情况

不去管默认方法,继承的接口直接继承默认方法

 //1.不去管默认方法 
 public  interface  anothertimeclient  extends  timeclient{ 

 } 

通过下面的测试代码,我们知道anothertimeclient接口直接继承了timeclient接口的默认方法 getzoneddatetime

 method[] declaredmethods = anothertimeclient. class .getmethods(); 

      for (method method:declaredmethods){ 

        system.out.println(method.tostring()); 

      }  

 //output: 

 //public default java.time.zoneddatetime xyz.johntsai.lambdademo.timeclient.getzoneddatetime(java.lang.string) 

重新声明默认方法,这样会使得这个方法变成抽象方法

 //重新声明默认方法,使之变为抽象方法 

 public  interface  abstractzonetimeclient  extends  timeclient{ 

    @override 

    zoneddatetime getzoneddatetime(string zonestring); 

 } 

测试可以发现 getzoneddatetime 方法由默认方法变为了抽象方法:

 method[] methods = abstractzonetimeclient. class .getmethods(); 

      for (method method:methods){ 

        system.out.println(method.tostring()); 

      } 

 //output:    

 //public abstract java.time.zoneddatetime xyz.johntsai.lambdademo.abstractzonetimeclient.getzoneddatetime(java.lang.string) 

重新定义默认方法,这样会使得方法被重写

 //3.重新定义默认方法 

 public  interface  handleinvalidzonetimeclient  extends  timeclient { 

    default  zoneddatetime getzoneddatetime(string zonestring){ 

      try  { 

        return  zoneddatetime.of(getlocaldatetime(), zoneid.of(zonestring)); 

      }  catch  (datetimeexception e) { 

        system.err.println( "invalid zone id: "  + zonestring + 

            "; using the default time zone instead." ); 

        return  zoneddatetime.of(getlocaldatetime(),zoneid.systemdefault()); 

      } 

    } 

 } 

实现 handleinvalidzonetimeclient 接口的类将拥有重写过的 getzoneddatetime 方法。

静态方法

在java8的接口中,我们不光能写默认方法,还能写静态方法。上面的例子中正好用到了静态方法。

 public  interface  timeclient { 

    // ... 

    static  public  zoneid getzoneid (string zonestring) { 

      try  { 

        return  zoneid.of(zonestring); 

      }  catch  (datetimeexception e) { 

        system.err.println( "invalid time zone: "  + zonestring + 

          "; using default time zone instead." ); 

        return  zoneid.systemdefault(); 

      } 

    } 

 

    default  public  zoneddatetime getzoneddatetime(string zonestring) { 

      return  zoneddatetime.of(getlocaldatetime(), getzoneid(zonestring)); 

    }   

 } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。