Java8 在接口的变化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/axuanqq/article/details/82773631

Java8 对接口的改变
1.增加了default方法和static方法,这两种方法完全可以有方法体

2.default方法属于实例,static方法属于类(接口)
3.接口中的静态方法不会被继承,接口中的静态变量会被继承

实例如下:
 

package com.xxf.lambda.java8features;

/**
 * com.xxf.lambda.java8features
 * 2018/9/19
 * author:asange
 * email:[email protected]
 **/
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:[email protected]
 **/
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:[email protected]
 **/
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:[email protected]
 **/
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:[email protected]
 **/
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:[email protected]
 **/
@FunctionalInterface
public interface TestInterface {
    
    void onlyOneAbstractMethod();
}


 

扫描二维码关注公众号,回复: 3372533 查看本文章

猜你喜欢

转载自blog.csdn.net/axuanqq/article/details/82773631
今日推荐