接口是一种引用数据类型,是抽象方法的集合,以关键字 interface 来声明。接口无法被实例化,但是它可以被实现。
Java 7 之后:常量 、抽象方法
Java 8 之后:默认方法、静态方法
Java 9 之后:静态方法、私有方法
public interface Iinterface {
//定义常量
public static final int NUM = 100;
//定义抽象方法
public abstract void funAbstract();
//定义默认方法
public default void funDefault() {
System.out.println("接口中的默认方法");
}
//定义静态方法
public static void funStatic(){
System.out.println("接口中的静态方法");
}
//定义普通私有方法
private void funPrivate(){
System.out.println("接口中的普通私有方法");
}
//定义静态私有方法
private static void funStaticPrivate(){
System.out.println("接口中的静态私有方法");
}
}
<1> 在任何版本的Java中,接口都可以定义抽象方法。
<2> 接口不能直接使用,必须有一个“实现类”来实现接口;
<3> 接口得“实现类”必须覆盖重写接口中的所有抽象方法;
<4> 接口中的抽象方法修饰符必须是两个固定的关键字:public abstract;这两个关键字可以选择性的进行省略,定义的方法依然是抽象方法。
public interface Iinterface01 {
public abstract void fun01();
abstract void fun02();
public void fun03();
void fun04();
}
public class Test01 implements Iinterface01{
@Override
public void fun01() {
System.out.println("抽象方法");
}
@Override
public void fun02() {
System.out.println("抽象方法");
}
@Override
public void fun03() {
System.out.println("抽象方法");
}
@Override
public void fun04() {
System.out.println("抽象方法");
}
}
注意:若实现类中没有覆盖重写接口中所有的抽象方法,那么该实现类也必须是抽象类。
public interface Iinterface02 {
//定义默认方法
public default void fun01(){
System.out.println("接口中的默认方法fun01()");
}
default void fun02(){
System.out.println("接口中的默认方法fun02()");
}
}
public class Test02 implements Iinterface02{
@Override
public void fun01() {
System.out.println("重写默认方法fun01()");
}
public static void main(String[] args) {
Test02 t = new Test02();
t.fun01();
}
}
从以上代码可以看出:
<1> 在定义默认方法时,public修饰符可以省略;
<2> 默认方法可以被实现类继承,直接调用;
<3> 默认方法也可被实现类覆盖重写。
public interface Iinterface03 {
//定义静态方法
public static void fun01(){
System.out.println("接口中的静态方法fun01()");
}
static void fun02(){
System.out.println("接口中的静态方法fun02()");
}
}
public class Test03 implements Iinterface03{
public static void main(String[] args) {
Test03 t = new Test03();
Iinterface03.fun01();
Iinterface03.fun02();
}
}
注意:接口中的静态方法不能通过实现类的对象来调用,只能通过接口名称直接调用。
<1> 普通私有方法:用于解决多个默认方法之间重复代码问题。
例如:在下面这段代码所示的接口中,定义了两个默认方法,但是可以发现两个方法的重复代码很多。
public interface Iinterface04 {
public default void fun01(){
System.out.println("static fun01()");
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i + j = " + (i+j));
}
}
}
public default void fun02(){
System.out.println("static fun02()");
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i + j = " + (i+j));
}
}
}
}
因此,就可以在接口中定义一个普通的私有方法来解决这一问题。
public interface Iinterface04 {
public default void fun01(){
System.out.println("static fun01()");
method();
}
public default void fun02(){
System.out.println("static fun01()");
method();
}
private void method(){
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i + j = " + (i+j));
}
}
}
}
<2> 静态私有方法:用来解决静态方法之间重复代码的问题。
该方法的作用与普通私有方法类似,在这里不进行过多阐述。
使用 public static final 三个关键字进行修饰,其作用相当于“常量”。
我们知道,在Java中,类与类之间只支持单继承,当然Object类就另当别论了,但是接口中支持多继承。
需要注意的是:<1> 多个父接口中的抽象方法可以重复;
<2> 多个父接口中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写。
<1> 接口中的成员变量其实就是常量;
<2> 接口中没有静态代码块或构造方法;
<3> 一个类只能继承一个父类,但是一个类可以实现多个接口,接口之间用逗号隔开;
<4> 如果实现类没有覆盖重写接口中的所有抽象方法,那么该实现类必须是一个抽象类;
<5> 如果实现类所实现的多个接口中存在重复的抽象方法,那么该实现类只需要覆盖重写一次该方法;
<6> 如果多个接口中存在重复的默认方法,那么继承多个接口得子接口或者实现多个接口得实现类,就必须重写该默认方法;
<7> 一个类的直接父类中的方法和实现的接口中的默认方法冲突,则优先调用父类中的方法。