30分钟入门Java8之默认方法和静态接口方法学习
前言
上一篇文章30分钟入门Java8之lambda表达式,我们学习了lambda表达式。现在继续Java8新语言特性的学习,今天,我们要学习的是默认方法和静态接口方法。
这一Java8的新语言特性,在AndroidN中也得到了支持。至于如何在Android开发中配置Java8的开发环境,请查看上一篇文章30分钟入门Java8之lambda表达式。
默认方法
默认方法让我们能给我们的软件库的接口增加新的方法,并且能保证对使用这个接口的老版本代码的兼容性。
下面通过一个简单的例子来深入理解下默认方法:
1.一天,PM说我们的产品需要获取时间和日期。于是我们就写了一个设置和获取日期时间的接口类TimeClient。
publicinterfaceTimeClient{ voidsetTime(inthour,intminute,intsecond); voidsetDate(intday,intmonth,intyear); voidsetDateAndTime(intday,intmonth,intyear, inthour,intminute,intsecond); LocalDateTimegetLocalDateTime(); }
以及这个接口的实现类SimpleTimeClient:
publicclassSimpleTimeClientimplementsTimeClient{ privateLocalDateTimelocalDateTime; publicSimpleTimeClient(){ localDateTime=LocalDateTime.now(); } @Override publicvoidsetTime(inthour,intminute,intsecond){ LocalTimelocalTime=LocalTime.of(hour,minute,second); LocalDatelocalDate=LocalDate.from(localDateTime); localDateTime=LocalDateTime.of(localDate,localTime); } @Override publicvoidsetDate(intday,intmonth,intyear){ LocalDatelocalDate=LocalDate.of(day,month,year); LocalTimelocalTime=LocalTime.from(localDateTime); localDateTime=LocalDateTime.of(localDate,localTime); } @Override publicvoidsetDateAndTime(intday,intmonth,intyear,inthour,intminute,intsecond){ LocalDatelocalDate=LocalDate.of(day,month,year); LocalTimelocalTime=LocalTime.of(hour,minute,second); localDateTime=LocalDateTime.of(localDate,localTime); } @Override publicLocalDateTimegetLocalDateTime(){ returnlocalDateTime; } @Override publicStringtoString(){ returnlocalDateTime.toString(); } publicstaticvoidmain(String[]args){ TimeClienttimeClient=newSimpleTimeClient(); System.out.println(timeClient.toString()); } }
2.可是PM说我们这个产品呐,不光国内用,各种其他时区的顾客也会使用。于是给你增加了新的需求:获取指定时区的日期和时间
以往我们都会这么做:
重写接口,增加方法
publicinterfaceTimeClient{ voidsetTime(inthour,intminute,intsecond); voidsetDate(intday,intmonth,intyear); voidsetDateAndTime(intday,intmonth,intyear,inthour,intminute,intsecond); LocalDateTimegetLocalDateTime(); //新增的方法 ZonedDateTimegetZonedDateTime(StringzoneString); }
这样我们的实现类也要相应的进行重写。
publicclassSimpleTimeClientimplementsTimeClient{ privateLocalDateTimelocalDateTime; ... ZonedDateTimegetZonedDateTime(StringzoneString){ returnZonedDateTime.of(getLocalDateTime(),getZoneId(zoneString)); } staticZoneIdgetZoneId(StringzoneString){ try{ returnZoneId.of(zoneString); }catch(DateTimeExceptione){ System.err.println("Invalidtimezone:"+zoneString+ ";usingdefaulttimezoneinstead."); returnZoneId.systemDefault(); } } }
这样写会导致我们要去重写每个实现了TimeClient接口的类。而这大大增加了我们的实现需求的负担。
正是为了解决Java接口中只能定义抽象方法的问题。Java8新增加了默认方法的特性。下面让我们来使用默认方法实现需求。
publicinterfaceTimeClient{ voidsetTime(inthour,intminute,intsecond); voidsetDate(intday,intmonth,intyear); voidsetDateAndTime(intday,intmonth,intyear, inthour,intminute,intsecond); LocalDateTimegetLocalDateTime(); staticZoneIdgetZoneId(StringzoneString){ try{ returnZoneId.of(zoneString); }catch(DateTimeExceptione){ System.err.println("Invalidtimezone:"+zoneString+ ";usingdefaulttimezoneinstead."); returnZoneId.systemDefault(); } } //默认方法 defaultZonedDateTimegetZonedDateTime(StringzoneString){ returnZonedDateTime.of(getLocalDateTime(),getZoneId(zoneString)); } }
默认方法关键字为default,以往我们只能在接口中定义只有声明没有实现的方法。有了默认方法,我们就能编写完整的方法。
这样我们就不需要修改继承接口的实现类,就给接口添加了新的方法实现。
publicstaticvoidmain(String[]args){ TimeClienttimeClient=newSimpleTimeClient(); System.out.println(timeClient.toString()); System.out.println(timeClient.getZonedDateTime("test")); }
继承含有默认方法的接口
当我们继承含有默认方法的接口时,一般有以下三种情况
不去管默认方法,继承的接口直接继承默认方法
//1.不去管默认方法 publicinterfaceAnotherTimeClientextendsTimeClient{ }
通过下面的测试代码,我们知道AnotherTimeClient接口直接继承了TimeClient接口的默认方法getZonedDateTime
Method[]declaredMethods=AnotherTimeClient.class.getMethods(); for(Methodmethod:declaredMethods){ System.out.println(method.toString()); } //output: //publicdefaultjava.time.ZonedDateTimexyz.johntsai.lambdademo.TimeClient.getZonedDateTime(java.lang.String)
重新声明默认方法,这样会使得这个方法变成抽象方法
//重新声明默认方法,使之变为抽象方法 publicinterfaceAbstractZoneTimeClientextendsTimeClient{ @Override ZonedDateTimegetZonedDateTime(StringzoneString); }
测试可以发现getZonedDateTime方法由默认方法变为了抽象方法:
Method[]methods=AbstractZoneTimeClient.class.getMethods(); for(Methodmethod:methods){ System.out.println(method.toString()); } //output: //publicabstractjava.time.ZonedDateTimexyz.johntsai.lambdademo.AbstractZoneTimeClient.getZonedDateTime(java.lang.String)
重新定义默认方法,这样会使得方法被重写
//3.重新定义默认方法 publicinterfaceHandleInvalidZoneTimeClientextendsTimeClient{ defaultZonedDateTimegetZonedDateTime(StringzoneString){ try{ returnZonedDateTime.of(getLocalDateTime(),ZoneId.of(zoneString)); }catch(DateTimeExceptione){ System.err.println("InvalidzoneID:"+zoneString+ ";usingthedefaulttimezoneinstead."); returnZonedDateTime.of(getLocalDateTime(),ZoneId.systemDefault()); } } }
实现HandleInvalidZoneTimeClient接口的类将拥有重写过的getZonedDateTime方法。
静态方法
在Java8的接口中,我们不光能写默认方法,还能写静态方法。上面的例子中正好用到了静态方法。
publicinterfaceTimeClient{ //... staticpublicZoneIdgetZoneId(StringzoneString){ try{ returnZoneId.of(zoneString); }catch(DateTimeExceptione){ System.err.println("Invalidtimezone:"+zoneString+ ";usingdefaulttimezoneinstead."); returnZoneId.systemDefault(); } } defaultpublicZonedDateTimegetZonedDateTime(StringzoneString){ returnZonedDateTime.of(getLocalDateTime(),getZoneId(zoneString)); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。