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));
}
}

30分钟入门Java8之默认方法和静态接口方法的更多相关文章

  1. 30分钟入门Java8之方法引用

    30分钟入门Java8之方法引用 前言 之前两篇文章分别介绍了Java8的lambda表达式和默认方法和静态接口方法.今天我们继续学习Java8的新语言特性--方法引用(Method Referenc ...

  2. Java8之默认方法和静态接口方法

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

  3. 30分钟入门Java8之lambda表达式

    前言 Google在今年发布Android N开发者预览版,一并宣布开始支持Java 8.我们终于能在Android开发中使用到Java8的一些语言特性了.目前支持: 默认方法 lambda表达式 多 ...

  4. Shell脚本编程30分钟入门

    Shell脚本编程30分钟入门 转载地址: Shell脚本编程30分钟入门 什么是Shell脚本 示例 看个例子吧: #!/bin/sh cd ~ mkdir shell_tut cd shell_t ...

  5. Objective-C 30分钟入门教程

    Objective-C 30分钟入门教程 我第一次看OC觉得这个语言的语法有些怪异,为什么充满了@符号,[]符号,函数调用没有()这个,但是面向对象的高级语言也不外乎类,接口,多态,封装,继承等概念. ...

  6. 正则表达式30分钟入门教程<转载>

    来园子之前写的一篇正则表达式教程,部分翻译自codeproject的The 30 Minute Regex Tutorial. 由于评论里有过长的URL,所以本页排版比较混乱,推荐你到原处查看,看完了 ...

  7. Python 30分钟入门指南

    Python 30分钟入门指南 为什么 OIer 要学 Python? Python 语言特性简洁明了,使用 Python 写测试数据生成器和对拍器,比编写 C++ 事半功倍. Python 学习成本 ...

  8. 【原创】30分钟入门 github

    很久没更新了,这篇文章重点在github的入门使用,读者可以下载github for windows shell,边看边操作,加深印象. 好了,30分钟的愉快之旅开始吧: 一.github使用的注意事 ...

  9. PHP正则表达式30分钟入门教程

    正则表达式30分钟入门教程 三个常用的知识点: 1.惰性匹配:正则引擎默认是贪婪的,若要最少重复的话,需要用到惰性匹配符 “?” 懒惰限定符 代码/语法 说明 *? 重复任意次,但尽可能少重复 +? ...

随机推荐

  1. 使用UEditor无法SetContent的问题

    无法SetContent是因为 <script id="txtContent" name="txtContent" type="text/pla ...

  2. spring mvc ajax 提交复杂数组类型

    The server refused this request because the request entity is in a format not supported by the reque ...

  3. servlet servlet基本概念和helloservlet实例

    java web目录结构: web.xml是重要配置文件,容器正是通过这个文件找到service方法. 用纯文本+tomcat组装简单servlet web 新建HelloServlet.java: ...

  4. css圆环百分比

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. 插件~Nuget中包与包的依赖关系

    在Nuget管理包时,有可能A包的存在需要B包的支持,A包在安装之前,需要先安装B包,这就叫做依赖关系,而在NUGET里,确实有这种概念,比如大叔的Lind.DDD.Manager包,它就依赖于Lin ...

  6. MyEclipse使用总结——MyEclipse文件查找技巧 ctrl+shift+R ctrl+H

    一.查找文件 使用快捷键[ctrl+shift+R]弹出弹出文件查找框,如下图所示: 二.查找包含某个字符串的文件 使用快捷键[ctrl+H]在弹出对话框中选File Search选项,然后在第一个文 ...

  7. HTML5 <a>标签的ping属性用法

    随着移动互联网用户井喷式的增长,web前端开发中的HTML5在近几年备受瞩目,越来越多的人从事html5开发相关工作.今天小编也来凑个热闹,和大家一起来谈谈HTML5中<a>标签的ping ...

  8. Delphi XE8,C++ Builder XE8,RAD Studio XE8 官方 ISO 文件下载,附激活工具

    RAD Studio XE8 v22.0.19027.8951 官方ISO下载(6.72G):http://altd.embarcadero.com/download/radstudio/xe8/de ...

  9. Node.js的颠覆者:PHP的Swoole扩展

          最近2年Node.js很火,异步与协程是网络开发方面热门的话题.在追求新技术的同时,也应该反思下这里面存在的陷阱.Node.js确实是一门有趣好玩有个性的语言和技术,动态性,全异步回调的方 ...

  10. HBase + Kerberos 配置示例(一)

    用过hbase的朋友可能都有过这样的疑问,我写一个java client,好像就提供了zookeeper quorum地址就连上hbase了,那么是不是存在安全问题?的确是,如何解决?hbase中引入 ...