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));
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。