Java教程

Java接口

本文主要是介绍Java接口,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.基本概念

  • 接口(interface)主要用来描述类具有什么功能,但不需要给出各个功能的具体实现。

    举个栗子:定义一个名为Person 人的接口,接口声明act() 动方法,人会动,但我们不知道人会怎么动,不同状态的人动作不一样。不同状态的人怎么动,就看实现Person接口的不同人的类如何实现这个方法。

    public interface Person{
        void act();
    }
    
  • 一个类可以实现(implements)一个或者多个接口

  • 接口可以继承接口,甚至能继承多个接口——接口的多继承。

  • 接口中的所有方法都自动属于public,因此在接口中声明的方法,不必用public来修饰,不过你非要用public来修饰也不是不可以。

  • 在JDK8以后可以在接口中实现一个或多个static或default修饰的方法。

    例如在上面的Person接口中增加两个方法实现:

    public interface Person{
        void act();//相当于public abstract void act();
        /*
        * 默认方法
        * 有的人不需要工作或赚钱,所以此方法可以让实现类的对象选择性调用,或者根据需求overrid此方法
        */
        default String work(){
            return "money";
        }
        static void sleep(){
            System.out.println("zzz");
        }
    }
    

    default修饰的方法work()能被接口Person的实现类所继承,在子类的的实例化对象中调用;

    static修饰的方法sleep(),是类方法,调用方式和普通类方法相同,即用Person.sleep();调用

  • 在JDK9以后接口还支持用private修饰非抽象方法,即私有方法私有类方法

    其中,私有方法供接口中非static修饰的非抽象方法调用,私有类方法可供接口中所有非抽象方法调用。

  • 接口中不能包含实例域,但是能包含static常量

    与接口中的方法都自动地被设置为 public—样,接口中的域都将被自动设为public static final 。

    例如:在Person接口中增加一个常量MAX_AGE=130

    public interface Person{
        int MAX_AGE=130;//等同于public static final int MAX_AGE=130;
        void act();
    }
    

问:抽象类和接口之间的区别是什么?他们不是都能包含抽象方法和方法实体吗?[1]

首先,一个类只能继承一个抽象类,但是一个类可以实现多个接口。

其次,一个抽象类可以通过实例变量(字段)保存一个通用状态,而接口是不能有实例变量的。

2.接口中默认方法的使用场景

  • 可选方法

例如上文例子中的work()方法,若该方法是抽象方法,那么实现Person的类,就必须实现该方法,哪怕该类用不到该方法。可若该方法是default默认方法,它会自动被实现类继承,实现类需要时调用,用不到不调用即可,而不用在实现类里写一个work()的空方法。

  • 行为的多继承

通过实现多个接口或者实现一个多继承接口,从而使得实现类获得重用多个接口默认方法的能力。

  • 多方法的组合

    public interface Person{
        void sleep();
        void work();
        //定义一个摸鱼的默认方法,将工作和睡觉组合,这样所有人都get到了摸鱼技能了
        default void moyu(){
            work();
            sleep();
        }
    }
    

3.默认方法冲突[2]

我们知道 Java 语言中一个类只能继承一个父类,但是一个类可以实现多个接口。随着默认方法在 Java 8 中引入,有可能出现一个类继承了多个方法但它们使用的是同样的函数签名。这种情况下,类会选择使用哪一个函数?Java解决这种冲突遵循以下三条规则:

    1. 类中的方法优先级最高。类或父类中的方法优先级高于任何默认方法。
    1. 如果第一条规则无法判断,那么子接口的优先级更高函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果 B 继承了 A,那么 B 就比 A 更加具体。
    1. 若依然无法判断,那么继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。
public interface A{
    default void hello(){
        System.out.println("Hello from A");
    }
}
public interface B extends A{
    default void hello(){
        System.out.println("Hello from B");
    }
}
public class C implements B,A{
    public static void main(String[] args) {
        new C().hello();//猜猜这里打印输出的是什么?
    }
}

  1. 摘自《Java实战》 ↩︎

  2. 摘自《Java实战》 ↩︎

这篇关于Java接口的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!