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