接口改动一下就要修改对应的实现类,为了兼容老接口,Java8新增了默认方法和静态方法;
对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现
1)静态方法可以直接调用,不能被重写
2)默认方法需要通过实现类,重写后实例化后调用
一个例子,演示默认方法、静态方法和实现类中对它们的重写,抽象方法doSomthing()就不赘述:
//一个有多个默认方法和静态方法的接口CommonInterface public interface CommonInterface { //抽象方法 public void doSomthing(); //默认方法 default void defaultMehtod() { System.out.println("CommonInterface's default method is running..."); } //默认方法可以有多个 default void anotherDefaultMehtod() { System.out.println("CommonInterface's second default method is running..."); } //静态方法 static void staticMethod() { System.out.println("CommonInterface's static method is running..."); } //静态方法也可以有多个 static void anotherStaticMethod() { System.out.println("CommonInterface's second static method is running..."); } }
// 一个跟上边一模一样的接口CommonInterface1 public interface CommonInterface1 { //抽象方法 public void doSomthing(); //默认方法 default void defaultMehtod() { System.out.println("CommonInterface1's default method is running..."); } //默认方法可以有多个 default void anotherDefaultMehtod() { System.out.println("CommonInterface1's second default method is running..."); } //静态方法 static void staticMethod() { System.out.println("CommonInterface1's static method is running..."); } //静态方法也可以有多个 static void anotherStaticMethod() { System.out.println("CommonInterface1's second static method is running..."); } }
实现类在尝试重写静态方法时报错,可见静态方法不允许重写:
public class CommonInterfaceImpl implements CommonInterface, CommonInterface1 { @Override public void doSomthing() { System.out.println("CommonInterfaceImpl.doSomthing(): 我们来学习Java8新特性吧!"); } @Override public void defaultMehtod() { System.out.println("CommonInterfaceImpl.defaultMehtod()-------------start"); CommonInterface.super.defaultMehtod(); CommonInterface1.super.defaultMehtod(); System.out.println("CommonInterfaceImpl.defaultMehtod()-------------end"); } @Override public void anotherDefaultMehtod() { System.out.println("CommonInterfaceImpl.anotherDefaultMehtod()-------------start"); CommonInterface.super.anotherDefaultMehtod(); CommonInterface1.super.anotherDefaultMehtod(); System.out.println("CommonInterfaceImpl.anotherDefaultMehtod()-------------end"); } }
客户端调用:
public class Client { public static void main(String[] args) { //默认方法 和 抽象方法需实现类实例化后调用 CommonInterface commonInterface = new CommonInterfaceImpl(); //抽象方法重写后调用 commonInterface.doSomthing(); //默认方法重写后调用 commonInterface.defaultMehtod(); commonInterface.anotherDefaultMehtod(); }
结果:
CommonInterface's static method is running... CommonInterface's second static method is running... CommonInterface1's static method is running... CommonInterface1's second static method is running... CommonInterfaceImpl.doSomthing(): 我们来学习Java8新特性吧! CommonInterfaceImpl.defaultMehtod()-------------start CommonInterface's default method is running... CommonInterface1's default method is running... CommonInterfaceImpl.defaultMehtod()-------------end CommonInterfaceImpl.anotherDefaultMehtod()-------------start CommonInterface's second default method is running... CommonInterface1's second default method is running... CommonInterfaceImpl.anotherDefaultMehtod()-------------end
函数式接口(Functional Interface)是只有一个抽象方法的接口。
@FunctionalInterface public interface FuncInterface { //只有一个抽象方法 public void reference(); //还可以有其他方法 //interface default method default void defaultMehtod() { System.out.println("This is a default method~"); } //interface second default method default void anotherDefaultMehtod() { System.out.println("This is the second default method~"); } //interface static method static void staticMethod() { System.out.println("This is a static method~"); } //interface second static method default void anotherStaticMethod() { System.out.println("This is the second static method~"); } }
Java 8添加一个新的包"java.util.function",通常用于lambda表达式和方法引用,包下有很多通用接口:
大致可以分为这几类:
3.1 消费型接口
Consumer 有一个accept(T t) 方法接受一个入参没有返回,只要符合这个格式的参数,无需再写函数式接口,可以直接写lambda表达式:
方法:
/** * buy方法有个Consumer<Integer>的入参 * @param money * @param consumer */ public static void buy(Integer money, Consumer<Integer> consumer) { consumer.accept(money); }
客户端调用:
public static void main(String[] args) { //消费型:第二个参数为实现了Consumer<T>接口accept(T t)方法的lambda表达式 buy(1000, money -> System.out.println("消费型-->我买面包花了:" + money + "元")); }
结果:
消费型-->我买面包花了:1000元
3.2 供给型接口
Supplier 有一个get()方法无入参一个返回:
方法:
/** * factory方法有个Supplier<Integer>的入参 * @param supplier * @return */ public static String factory(Supplier<String> supplier) { return supplier.get(); }
客户端调用:
public static void main(String[] args) { //供给型:参数为实现了Supplier<Integer>接口get()方法的lambda表达式 String phone = factory(() -> {return "Apple8";}); System.out.println("供给型-->富士康生产的有名的手机是:" + phone); }
结果:
供给型-->富士康生产的有名的手机是:Apple8
3.3 函数型接口
Function接口有一个apply(T t)方法接受入参有一个返回:
方法:
/** * convert方法有个Function<String, Integer>的入参 * @param str * @param function * @return */ public static Integer convert(String str, Function<String, Integer> function) { return function.apply(str); }
客户端调用:
public static void main(String[] args) { //函数型:参数为实现了Function<String, Integer>接口apply(T t)方法的lambda表达式 Integer num = convert("666", x -> Integer.parseInt(x)); System.out.println("函数型-->字符型666被转换成了数字: "+ num); }
结果:
函数型-->字符型666被转换成了数字: 666
3.4 断言型接口
Predicate 有一个test(T t)方法有一个入参并返回一个boolean:
方法:
/** * isNoble方法有个Predicate<String>的入参 * * @param name * @param predicate * @return */ public static String isNoble(String name, Predicate<String> predicate) { if (predicate.test(name)) return "贵族"; return "平民"; }
客户端调用:
public static void main(String[] args) { //断言型:参数为实现了Predicate<String>接口test(T t)方法的lambda表达式 String na = "尼古拉斯赵四"; String noble = isNoble(na, (name) -> !"".equals(name) && name.contains("尼古拉斯")); System.out.println("断言型-->从你的名字就可以看出你是个:" + noble); }
结果:
断言型-->从你的名字就可以看出你是个:贵族
涉及代码:–>GitHub
参考文献:
[ 1 ]Java8函数式编程/(英)Richard Warburton著;王群锋译。–北京:人民邮电出版社,2015-03-01.
[ 2 ] http://www.importnew.com/26080.html
[ 3 ] http://java8.in/java-8-lambda-expression/
[ 4 ] https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#approach6
[ 5 ] https://winterbe.com/posts/2014/03/16/java-8-tutorial/
上一个:布偶猫很少有人养(布偶不好养吗)