概念:
- 接口是更加彻底的抽象,接口中全部是抽象方法。接口是不能直接创建对象的。
- 从JDK8之后,接口中不再只是抽象方法,接口还可以有默认方法(也就是实例方法),和静态方法了,还包含了私有实例方法和私有静态方法
- 在JDK8之前,接口中的成分包含:抽象方法和常量。JDK8以后可以定义非抽象方法,但是需要使用default关键字修饰。
- 接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写!
- 在接口中定义的成员变量默认会加上: public static final修饰。也就是说在接口中定义的成员变量实际上是一个常量。这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接
- Java中接口存在的意义:用来定义规范,用来做功能的拓展
接口的使用思路:
- 发现一个类都是抽象方法,就可以把这个类改进为一个接口
- 设计到了接口大面积更新的方法,不想去修改每一个实现类,就可以把这个更新的方法改为带有方法体的默认方法
- 希望默认方法调用的更加简洁,可以考虑设计为static静态方法(需要去掉default关键字)
- 默认方法中出现了重复的代码,可以考虑抽取一个私有方法(需要去掉default关键字)
创建格式:
修饰符 interface 接口名称{
// 抽象方法
}
public interface Inter {public abstract void add(int a, int b);
}public class InterImpl implements Inter {@Overridepublic void add(int a, int b) {System.out.println("我是接口的实现类");}
}
接口的实现类
类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类(子类),实现使用
implements
关键字
接口是可以被多实现的
实现类必须重写接口中的所有抽象方法,或者定义自身为抽象类。
实现接口的格式:
修饰符 class 类名 implements 接口1,接口2,接口3...{
}
实现接口案例:
假如我们定义一个运动员的接口,代码如下:
public interface SportMan {void run(); // 抽象方法,跑步。void law(); // 抽象方法,遵守法律。String compittion(String project); // 抽象方法,比赛。
}
定义一个乒乓球运动员类,实现接口:
public class PingPongMan implements SportMan {@Overridepublic void run() {System.out.println("乒乓球运动员稍微跑一下!!");}@Overridepublic void law() {System.out.println("乒乓球运动员守法!");}@Overridepublic String compittion(String project) {return "参加" + project + "得金牌!";}
}
测试类:
public static void main(String[] args) {
// 创建实现类对象。PingPongMan zjk = new PingPongMan();zjk.run();zjk.law();System.out.println(zjk.compittion("全球乒乓球比赛"));}
接口的多实现:
- 类与接口之间的关系是多实现的,一个类可以同时实现多个接口。
代码演示:先定义两个接口
// 法律规范:接口public interface Law {void rule();}// 这一个运动员的规范:接口public interface SportMan {void run();}
定义实现类
public class JumpMan implements Law, SportMan {@Overridepublic void rule() {System.out.println("尊长守法");}@Overridepublic void run() {System.out.println("训练跑步!");}}
注意:
接口多实现,多个接口存在同名的静态方法不会有冲突,因为只能通过各自的接口名访问静态发方法。
接口的优先级:
当一个类,继承另一个类,并且,又实现多个接口时,父类中的成员方法与接口中的默认方法重名时,子类优先执行父类的成员方法(就近原则),可以理解为:谁离我近我就用谁的。
接口与继承:
Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。
说明:
- 类和接口是实现关系
- 接口与接口是继承关系
- 接口继承接口就是把其他接口的抽象方法与本接口进行了合并。
- 继承多个接口并且有相同的方法名时,子类必须重写接口同名的方法
public interface InterA {void showA();default void method() {System.out.println("InterA");}
}public interface InterB {void showB();default void method() {System.out.println("InterB");}
}public interface InterC extends InterA, InterB {@Overridedefault void method() {System.out.println("子类必须重写");}
}
接口中的方法:
- 默认方法:
JDK8以后允许接口中定义非抽象方法,但是需要用default关键字修饰,用于解决接口升级问题,默认方法不是抽象方法,不被强制重写,实现类重写默认方法不加default
实现类实现了多个接口,多个接口中存在相同的方法声明,子类必须重写
public default void show() {System.out.println("我就是默认方法");}
- 静态方法:
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public static void show() { }
- 私有方法和私有静态方法:
私有方法产生原因:
- Java 9中新增了带方法体的私有方法,这其实在Java 8中就埋下了伏笔:Java8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java9增加私有方法的必然性。
- 默认方法可以调用私有的静态方法和非静态方法
静态方法只能调用私有的静态方法
私有方法外类调用不了
格式:
// 私有方法private void show() { }// 私有静态方法private static void method() { }
总结:
实现类直接访问接口的非私有方法,接口非私有静态方法通过类名调用。