Ps1:接口命名规则:IXxx...
Ps2:接口中的interface前面的public abstract,方法前面的public abstract,属性前面的public static final都可以省略的。可以通过继承该接口的类查看报错的原因反推推出系统默认的修饰符等(如图)。
报错提示要大于等于父类的修饰符,父类此时是没有写修饰符,那么如果是 default 修饰符的话,那么子类这里不写应该也是OK的,protected 同理失败,推论可得是 public 修饰符。
Ps3:static final 也同上可以反推出。
Ps4:如果接口中的变量和implements该接口的类的变量同名,则倘若用接口声明该类则调用的是接口中的变量;否则用派生类调用的是派生类的变量。
这没什么难理解的,记住之前的一点:因为静态成员无法被重写只是被隐藏,所以这里根本就没重写父类这一说法,而父类本身就不能调用子类特有的方法,自然而然肯定调的还是父类自己的静态成员。
Ps5:JDK 1.8 开始(如图)
- 新增 静态成员调用:接口名.静态成员
- 新增 default成员调用:接口名.super.default 成员 或 接口实例对象.default 成员(这里的“default”不是访问修饰符,而是有这个关键字!!!)
Tip:在重写“default”方法的时候,默认省略了“default”关键字。
Ps6:关于多接口中重名默认方法处理的解决方案:
- 如果一个类没有继承父类,而且遇上接口中重名默认方法,则需要自己在该类中写一个一样的默认方法来解决冲突,否则该类报错CE(如图)
- 如果一个类继承了父类,而且遇上接口中重名默认方法,以及父类中也有重名默认方法,则父类的重名方法优先(不会报错,因为父类已经实现了,而子类继承了),如果继续在该类重写该方法时,重写的是父类的方法,自然而然接口去调用的也是该类重写的方法(如图)
Ps7:关于多重接口名常量处理的解决方案:
- 如果一个类没有继承父类,而且遇上接口中重名常量名,则需要"接口名.常量名"来解决冲突(如图)
- 如果一个类继承了父类,而且遇上接口中重名常量名,以及父类中也有重名常量名(这次不会像上次默认方法可以解决冲突),则需要在该子类中,编写一个同样的常量名以解决冲突(如图)
Ps8:接口也支持接口间的继承,而且是多继承;那如果接口继承的父接口遇到同名的默认方法怎么办?只需要在子接口重写同名的默认方法即可。
实战
Java的interface中,成员变量的默认修饰符为:public static final
所以我们在interface中定义成员变量的时候,可以
- public static final String name = "张三";
- String name = "张三";
以上两种都可以,老司机一般都是第二种。既然是静态最终的变量,也就意味着在外面访问的时候不能修改这个成员变量的值。所以在接口中定义成员变量的,一般都是常量。不会修改的。如果要进行修改的话,定义在接口具体实现类中。
说完成员变量的默认修饰符,顺便也提下方法的默认修饰符,方法的默认修饰符是:public abstract
即:公共抽象的,就是用来被实现该接口的类去实现该方法。所以在接口中定义方法时候,也有两种方式
- public abstract List getUserNames(Long companyId);
- List getUserNames(Long companyId);
同样老司机都是第二种。
接口只是对一类事物属性和行为的更高次抽象;对修改关闭,对扩展开放,可以说是java中开闭原则的一种体现吧。