一、java8新特性
1、函数式接口
当接口里面只有一个抽象方法的时候,就是函数式接口,可以使用注解强制约束接口只能有一个抽象方法。
注解:从java5开始引入注解,对字节码文件进行一些说明。
@FunctionalInterface注解的作用:在编译时告诉编译器该接口只能有一个抽象方法。
注:
1、该注解在java.lang包下,不用引入
2、Lambda表达式只能针对函数式接口使用
2、接口里面的静态方法
从java8开始,接口里面可以有静态方法,和普通类的静态方法类似,使用static修饰 ,但接口里面只能是public的
[public] static <返回值类型><方法名>[形参列表]{
//方法体
}
3、接口里面的默认方法
从java8开始,除了可以在接口里面写静态方法,还可以写非静态方法,但是必须用 default 修饰。
默认方法可以被继承。
注:
1、default方法和static方法均只能被public修饰
2、如果继承了多个父接口,有重复的默认方法被继承到子接口,必须使用super引用明确指定调用哪个接口的默认方法。
在子接口必须重写重复的方法,并使用下面的语法。
<父接口名>.super.<重复方法名>([参数]);
3、同样地,对于一个类同时实现了多个接口,而这些接口均含有同样的默认方法的情况和2类似。
4、父接口的抽象方法,在子接口里面可以使用默认方法实现,这样实现类里面就无需再实现了。
如果实现类再去实现的话就是方法的覆盖了。
5、如果父接口有一个默认方法,在子接口里可以重写为抽象方法(去掉父接口的行为)。
二、代码描述
1、Interface1111.java
/**
* @Title: Interface1.java
* @Package com.lty.java8
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午5:41:40
* @version V1.0
*/
package com.lty.java8.functionalinterface;
interface Interface1{
//只有一个抽象方法,自动变为函数式接口
void test();
}
//超过一个抽象方法,不是函数式接口
interface Interface2{
void test1();
void test2();
}
//包括继承父接口的抽象方法和本身定义的抽象方法总共不能超过1个
//@FunctionalInterface
interface Interface3{
void test1();
void test2();
}
/**
* @ClassName: Interface1
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午5:41:40
*
*/
public class Interface1111 {
}
2、RemoveDefaultMethod.java
/**
* @Title: RemoveDefaultMethod.java
* @Package com.lty.java8.functionalinterface
* @Description: TODO
* @author Liu
* @date 2017年12月18日 下午5:53:43
* @version V1.0
*/
package com.lty.java8.functionalinterface;
interface E{
default void test(){
System.out.println("接口 E里面的默认方法");
}
}
interface F extends E{
void test();
}
/**
* @ClassName: RemoveDefaultMethod
* @Description: TODO
* @author Liu
* @date 2017年12月18日 下午5:53:43
*
*/
public class RemoveDefaultMethod {
public static void main(String[] args) {
E e = new E(){};
e.test();
//F接口已经将E接口里面的默认方法重写为抽象方法了,所以需要在实现类重写此抽象方法
F f = new F(){
@Override
public void test() {
System.out.println("gaga");
}
};
f.test();
}
}
3、TestDefaultMethodMain.java
/**
* @Title: TestDefaultMethodMain.java
* @Package com.lty.java8.functionalinterface
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午6:09:35
* @version V1.0
*/
package com.lty.java8.functionalinterface;
interface TestDefaultMethod{
//使用default修饰的方法,表示实例方法, 必须通过实例来访问
default void test(){
System.out.println("接口里面的默认方法" + this);
}
}
/**
* @ClassName: TestDefaultMethodMain
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午6:09:35
*
*/
public class TestDefaultMethodMain {
public static void main(String[] args) {
//使用匿名内部类初始化实例
TestDefaultMethod testDefaultMethod = new TestDefaultMethod() {
};
//使用对象访问默认方法
testDefaultMethod.test();
}
}
4、TestMultiInterfaces.java
/**
* @Title: TestMultiInterfaces.java
* @Package com.lty.java8.functionalinterface
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午6:19:59
* @version V1.0
*/
package com.lty.java8.functionalinterface;
interface A{
default void test(){
System.out.println("接口A里面的默认方法");
this.test2();
}
void test2();
}
interface B{
default void test(){
System.out.println("接口B里面的默认方法");
}
void test2();
}
//这时候在A、B里面都有test方法,系统不知道使用哪个方法
//可以在子接口重写该方法,明确指定调用哪个父接口的方法
interface C extends A,B{
//重写父接口的默认方法
default void test(){
//明确指定引用的父接口,使用super引用调用父接口的默认方法
//<父接口名>.super.<重复方法名>([参数])
A.super.test();
}
//在接口中可以使用默认方法实现父接口的抽象方法
default void test2(){
System.out.println("在子接口使用默认方法实现父接口的抽象方法");
}
}
class D implements A, B{
//子接口或实现类在重写方法的时候,修饰符必须相同或更大
//[public] 修饰符在实现类中不能被隐藏
public void test(){
//如果实现了多个接口,有重复的方法,实现类必须重写该重复方法,强制指定需覆盖哪个接口的方法。
B.super.test();
}
/* (非 Javadoc)
* <p>Title: test2</p>
* <p>Description: </p>
* @see com.lty.java8.functionalinterface.A#test2()
*/
@Override
public void test2() {
System.out.println("实现test2抽象方法");
}
}
/**
* @ClassName: TestMultiInterfaces
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午6:19:59
*
*/
public class TestMultiInterfaces {
public static void main(String[] args) {
C c = new C(){};
c.test();
D d = new D();
d.test();
c.test2();
d.test2();
C c2 = new C(){
public void test2(){
System.out.println("匿名内部类里重写方法..");
}
};
c2.test2();
}
}
5、TestStaticMethodMain.java
/**
* @Title: TestStaticMethod.java
* @Package com.lty.java8.functionalinterface
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午5:55:48
* @version V1.0
*/
package com.lty.java8.functionalinterface;
//是一个抽象接口,因为本接口只有一个抽象方法
interface TestStaticMethod{
void test();
//静态方法不是抽象方法,static和abstract不可能同时存在
static void test2(){
System.out.println("接口里面的静态方法,直接可以使用接口名调用");
}
//自从接口可以 有静态方法,从此接口可以写main方法,可以作为程序的入口
// public static void main(String[] args) {
// //调用接口的静态方法
// TestStaticMethod.test2();
// }
}
/**
* @ClassName: TestStaticMethod
* @Description: TODO
* @author Liu
* @date 2017年12月17日 下午5:55:48
*
*/
public class TestStaticMethodMain
{
public static void main(String[] args) {
//调用接口的静态方法
TestStaticMethod.test2();
}
}