Java8 对接口的改变
1.增加了default方法和static方法,这两种方法完全可以有方法体
2.default方法属于实例,static方法属于类(接口)
3.接口中的静态方法不会被继承,接口中的静态变量会被继承
实例如下:
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
public interface IUser {
static void say() {
System.out.println("say_" + IUser.class);
}
default void eat() {
System.out.println("eat_" + IUser.class);
}
}
在这里定义了一个接口,接口中有一个静态方法和一个默认的成员方法,我们申明一个实现类
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
public class Student implements IUser {
public static void main(String[] args) {
Student student = new Student();
student.eat();
Student.say();
IStudent.say();
}
}
运行结果:
Error:(15, 16) java: 找不到符号
符号: 方法 say()
位置: 类 com.xxf.lambda.java8features.Student
可以看到Student.say()方法并不能调用到(这个静态方法是接口中实现的),所以接口中静态方法并不能继承;
同时编译器也智能地提示了我们,不能这么干
我们知道类可以实现多个接口,如果这些接口都有这样的静态方法和默认方法,从上面我们可以得知,静态方法是不能继承的,那么智能xxxInterface.staticmethod()这样调用,那么同名的默认方法怎么办呢?到底是调用的哪个默认方法呢?
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
public interface IStudent {
static void say() {
System.out.println("say_" + IStudent.class);
}
default void eat() {
System.out.println("eat_" + IStudent.class);
}
}
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
public class Student implements IUser, IStudent {
public static void main(String[] args) {
Student student = new Student();
student.eat();
}
}
运行结果:
Error:(9, 8) java: 类 com.xxf.lambda.java8features.Student从类型 com.xxf.lambda.java8features.IUser 和 com.xxf.lambda.java8features.IStudent 中继承了eat() 的不相关默认值
得出结论:
如果一个实现类 继承了两个接口(这两个接口没有继承关系,有同名的默认方法),那么必须在实现类,显示声明,否则编译器不知道调用哪个而报错
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
public class Student implements IUser, IStudent {
public static void main(String[] args) {
Student student = new Student();
student.eat();
}
//实现类必须再实现一遍
@Override
public void eat() {
}
}
而且,还可以用特殊语法,指定我现在要实现的是那个接口的默认方法,如:
@Override
public void eat() {
IUser.super.eat();
}
语法格式:XXinterface.super.重名method();
如果两个含同名的默认方法,有继承关系呢?
答案肯定是 可以的,用最近一个爹的方法
在java8中有一个特别注解,用于修饰接口
package java.lang;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
用于限定接口只能有一个抽象方法,用法如下
package com.xxf.lambda.java8features;
/**
* com.xxf.lambda.java8features
* 2018/9/19
* author:asange
* email:xuanyouwu@163.com
**/
@FunctionalInterface
public interface TestInterface {
void onlyOneAbstractMethod();
}