JDK8新特性3——函数式接口

1. JDK8接口新增的两个方法

jdk8之前的接口

interface 接口名 {
    静态常量;
    抽象方法
}

JDK8对接口的增强,接口还可以有默认方法和静态方法

JDK8接口:

interface {
    静态常量;
    抽象方法;
    默认方法;
    静态方法;
}

1.1 接口默认方法

1.1.1 定义格式

interface 接口名{
    修饰符 default 返回值类型 方法名(){
        body
    }
}

1.1.2 使用

方式一:实现类直接调用接口的默认方法

方式二:实现类也可以重写接口的默认方法

例如:定义三个接口A、B、C,B和C都实现A

package com.hm.lambda;

public interface AA {
    public default void test01(){
        System.out.println("接口AA的默认方法");
    }
}



package com.hm.lambda;

// 实现类可以直接使用AA的默认方法
public class BB implements AA{
}


package com.hm.lambda;

// 实现类可以重写AA的默认方法
public class CC implements AA {
    @Override
    public void test01() {
        System.out.println("我是CC重写的方法");
    }
}

然后在分别调用CC和BB中的方法

 public static void main(String[] args) {
        BB bb = new BB();
        bb.test01();
        CC cc = new CC();
        cc.test01();
    }

运行结果如图:

1.2 接口静态方法

为了方便扩展,JDK8接口新增了静态方法

1.2.1 定义格式

interface 接口名 {
    修饰符 static 返回值类型 方法名(){
        代码;
    }
}

1.2.2 使用

直接使用  接口名.静态方法  调用即可

例如:

package com.hm.lambda;

public interface AA {
    public default void test01(){
        System.out.println("接口AA的默认方法");
    }

    public static void test02(){
        System.out.println("静态方法test02");
    }
}

调用:

 public static void main(String[] args) {
        AA.test02();
    }

注意:接口中的静态方法,不能被继承,不能被重写

1.2.3 接口默认方法与静态方法的区别

1)默认方法通过实例调用,静态方法通过接口名调用

2)默认方法可以被继承,实现类可以直接使用接口默认方法,也可以重写默认方法

3)静态方法不能被继承,实现类不能重写接口静态方法,只能使用接口名调用

小结:什么时候定义默认方法,什么时候定义静态方法了?当该方法需要被继承或者覆写的时候,就用default方法,否则用静态方法。

2. 认识函数式接口

        函数式接口(FunctionalImplement)是一种只含有一个抽象方法声明的接口,但是可以有多个非抽象方法的接口。类似于Java中的Marker Interface标记类型接口,比如java.io.Serializable等都是没有方法声明或属性声明的接口,主要用于通过instanceof就直接能探测一个实例是否是一个特定接口的实例。

        函数式接口也是一个接口,该接口中只能有一个抽象的方法,这种类型的接口也称之为SAM接口。

@FunctionalInterface
public interface LamFilter {
    Boolean filter(Apple apple);
}

         Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。加不加@FunctionalInterface对于接口是不是函数式接口没有影响,该注解只是提醒编译器去检查该接口是否仅包含一个抽象方法。如上例所示,在接口定义上加上注解@FunctionalInterface声明该接口是一个函数式接口。

2.1 函数式接口的特性

2.1.1 允许定义默认方法

默认方法不是抽象的,有一个默认的实现,通过实现类直接调用,不需要实现类实现该方法,提高了扩展性!

@FunctionalInterface
interface HelloWorld {
    void print(String str);
    //默认方法
    default void print2(String message) {
       System.out.println(message);
    }
}

注意:默认(default)方法只能通过接口的实现类来调用,不需要实现方法,也就是说接口的实现类可以继承或者重写默认方法。  

2.1.2 允许定义静态方法

静态方法不能是抽象方法,是一个已经实现了的方法,直接接口调用。跟普通的static方法是一样的,不需要实现类去调用

@FunctionalInterface
interface HelloWorld {
    void print(String str);
    //静态方法
    static void print3(String message) {
        System.out.println(message);
    }
}

注意:静态(static)方法只能通过接口名调用,不可以通过实现类的类名或者实现类的对象调用。就跟普通的静态类方法一样,通过方法所在的类直接调用 

2.1.3. 允许定义java.lang.Object里的public方法

        这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了Object类,包含了来自 java.lang.Object里对这些抽象方法的实现;

2.1.4 允许子接口继承多个父接口

        允许子接口继承多个父接口,但每个父接口中都只能存在一个抽象方法,且必须是相同的抽象方法

注意:函数式接口,有且仅有一个抽象方法,Object的public方法除外。

3. 自定义函数式接口

3.1 自定义参数个数的函数式接口        

我们发现,JDK提供的BiFunction最多只有2个参数,如果我们有3个参数的该怎么办了?这个时候就需要使用自定义的函数式接口来实现了!

例如:

Orage.java

package com.bjc.demo1;

public class Orage {
    private  String color;
    private Double price;
    private Double weight;
    
    public Orage(String color, Double price, Double weight) {
        this.color = color;
        this.price = price;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Double getWeight() {
        return weight;
    }

    public void setWeight(Double weight) {
        this.weight = weight;
    }
}

 自定义函数接口ThreeFunction:

package com.bjc.lambda.demo1;

@FunctionalInterface
public interface ThreeFunction<T,U,V,R> {
    R apply(T t,U u,V v);
}

函数式接口的使用:

ThreeFunction<String,Double,Double,Orage> tFunc = Orage :: new;
Orage orage = tFunc.apply("red", 3.99, 0.78);
System.out.println(orage);

3.2 自定义无参数函数式接口

接口定义:

interface InterfaceExample{
	Example create(String name);
}

使用:

public static void main(String[] args) {
	InterfaceExample com =  Example::new;
	Example bean = com.create("hello world");
	System.out.println(bean.name);
}

注意:Example是一个pojo类

发布了205 篇原创文章 · 获赞 9 · 访问量 7920

猜你喜欢

转载自blog.csdn.net/weixin_43318134/article/details/104426168