接口甚至比抽象类还抽象,他只代表某个确切的功能!也就是只包含方法的定义,甚至都不是一个类!接口一般只代表某些功能的抽象,接口包含了一些列方法的定义,类可以实现这个接口,表示类支持接口代表的功能(类似于一个插件,只能作为一个附属功能加在主体上,同时具体实现还需要由主体来实现)

实际上接口的目标就是将类所具有某些的行为抽象出来。

比如说,对于人类的不同子类,学生和老师来说,他们都具有学习这个能力,既然都有,那么我们就可以将学习这个能力,抽象成接口来进行使用,只要是实现这个接口的类,都有学习的能力:

public interface Study {    //使用interface表示这是一个接口
    void study();    //接口中只能定义访问权限为public抽象方法,其中public和abstract关键字可以省略
}

我们可以让类实现这个接口:

public class Student extends Person implements Study {   //使用implements关键字来实现接口
    public Student(String name, int age, String sex) {
        super(name, age, sex, "学生");
    }
 
    @Override
    public void study() {    //实现接口时,同样需要将接口中所有的抽象方法全部实现
        System.out.println("我会学习!");
    }
}

有些人说接口其实就是Java中的多继承,但是我个人认为这种说法是错的,实际上实现接口更像是一个类的功能列表,作为附加功能存在,一个类可以附加很多个功能,接口的使用和继承的概念有一定的出入,顶多说是多继承的一种替代方案。

接口跟抽象类一样,不能直接创建对象,但是我们也可以将接口实现类的对象以接口的形式去使用:

当做接口使用时,只有接口中定义的方法和Object类的方法,无法使用类本身的方法和父类的方法。

从Java8开始,接口中可以存在方法的默认实现:

public interface Study {
    void study();
 
    default void test() {   //使用default关键字为接口中的方法添加默认实现
        System.out.println("我是默认实现");
    }
}

如果方法在接口中存在默认实现,那么实现类中不强制要求进行实现。

接口不同于类,接口中不允许存在成员变量和成员方法,但是可以存在静态变量和静态方法,在接口中定义的变量只能是:

public interface Study {
    public static final int a = 10;   //接口中定义的静态变量只能是public static final的
  
      public static void test(){    //接口中定义的静态方法也只能是public的
        System.out.println("我是静态方法");
    }
    
    void study();
}

最后我们来介绍一下顶层Object类中提供的克隆方法,为啥要留到这里才来讲呢?因为它需要实现接口才可以使用:

package java.lang;
 
public interface Cloneable {    //这个接口中什么都没定义
}

实现接口后,我们还需要将克隆方法的可见性提升一下,不然还用不了:

public class Student extends Person implements Study, Cloneable {   //首先实现Cloneable接口,表示这个类具有克隆的功能
    public Student(String name, int age, String sex) {
        super(name, age, sex, "学生");
    }
 
    @Override
    public Object clone() throws CloneNotSupportedException {   //提升clone方法的访问权限
        return super.clone();   //因为底层是C++实现,我们直接调用父类的实现就可以了
    }
 
    @Override
    public void study() {
        System.out.println("我会学习!");
    }
}

虽然Student对象成功拷贝,但是其内层对象并没有进行拷贝,依然只是对象引用的复制,所以Java为我们提供的clone方法只会进行浅拷贝。