认识接口
- java提供了一个关键字interface,用这个关键字可以定义出一个特殊的结构:接口
- 在接口里面定义的变量,不管加不加public static final修饰都默认为常量,必须赋初值
- 在接口里面定义的方法,不管加不加public abstract修饰都默认为抽象方法
- 接口中不能有构造器、代码块
-
public interface A { //成员变量(常量) //成员方法(抽象方法) }
- 接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类
修饰符 class 实现类 implements 接口1,接口2,接口3,...{......} - 一个类可以实现多个接口(接口可理解为义父),实现类实现多个接口,必须重写全部接口的所有抽象方法,否则实现类需要定义为抽象类
接口的好处
- 弥补了类单继承的不足,一个类可以同时实现多个接口
- 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现
示例:
假设一个类继承了学生类,但是这个类还想兼职别的工作,那就可以使用接口来实现
class Student{} //学生类
class A extends Student implements Waiter, Driver {} //一个类继承了学生类,同时也实现了服务员和司机类
interface Waiter {} //服务员接口
interface Driver {} //司机接口
public class Test {
public static void main(String[] args) {
Student a1 = new A(); //他可以是学生
Waiter a2 = new A(); //也可以是服务员
Driver a3 = new A(); //也可以是司机
}
}
- 既然是为了添加一些功能方法,为什么不直接在类里面多写几个呢?
- 直接往类里面写的话,别人可能根本不知道你有这些功能,而使用接口实现的话,接口就相当于一个身份证明,实现了服务员接口,司机接口,别人一看也就知道你拥有哪些的功能,从而可以放心的把你当作哪种对象来使用了
从jdk8开始,接口中新增的三种方法
- 默认方法:必须使用default关键字修饰,默认会被public修饰
default void test(){...}
就是实例方法:也就是对象的方法,必须使用实现类的对象来访问 - 私有方法:必须使用private修饰
private void test(){...}(jdk9开始才支持)
也是实例方法:对象的方法,在接口的其它方法(默认方法、静态方法、私有方法)里面访问 - 静态方法:必须使用static修饰,默认会被public修饰
static void test(){...}
只能使用接口名去调用
- 新增的这些方法增强了接口的能力,更便于项目的拓展和维护
接口的多继承
一个接口可以同时继承多个接口
public interface C extends B ,A{...}
- 便于实现类去实现:如果一个实现类需要实现多个接口,就可以使用一个接口继承那多个接口,然后实现类只需要实现这一个接口就相当于实现了那多个接口了,如果实现类只有一个可能作用不明显,但是如果有很多个实现类就可以体现出减少代码量的优势了
接口的注意事项
接口其他注意事项
- 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承
- 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现
- 一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的
示例代码:class Fu{ public void test(){ System.out.println("父类的test执行了"); } } interface E{ default void test(){ System.out.println("E接口的test执行了"); } } class Zi extends Fu implements E{ } public class Test { public static void main(String[] args) { Zi z = new Zi(); z.test(); } }
结果:
- 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可
示例代码:interface A{ default void test(){ System.out.println("A的test执行了"); } } interface B{ default void test(){ System.out.println("B的test执行了"); } } class C implements A, B{ @Override public void test() { System.out.println("C的test执行了"); //A和B的test方法重复了,重写解决报错 } } public class Test { public static void main(String[] args) { C c = new C(); c.test(); } }
结果: