文章目录
- 接口不是类,不能使用 new 实例化一个接口;
- 不能构造接口的对象,但可声明接口的变量;
- 接口变量必须引用实现了接口的类对象;
- 可以使用 instanceof 检查一个对象是否实现了某个特定的接口;
- 可以建立类的继承关系一样,接口可以继承接口进行扩展;
- 接口中不能包含实例域或静态方法,但可包含常量;
- 接口中声明的方法自动地设置为 public;
- 接口中的域(即常量)自动地设置为 public static final;
- 静态方法。
JavaSE8 允许在接口中增加静态方法; - 默认方法。
可以为接口方法提供一个默认实现,必须使用 default 修饰符标记这个方法; - 解决默认方法冲突问题:
如果接口中将一个方法定义为默认方法,然后在超类或另一个接口中定义了同样的方法。就要解决冲突,规则如下:
① 超类优先。如果超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略。
②接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,必须覆盖这个方法来解决冲突。
③类优先原则。如果一个类扩展了一个超类,同时实现了一个接口,并且从超类和接口继承了相同的方法。此种情况使用类优先原则,接口的默认方法会被忽略。
接口PersonInfo
/** * @version $Id: PersonInfo.java, v 0.1 2017年6月9日 下午5:19:14 */ public interface PersonInfo { //方法都自动设置为public void printAge(); //常量自动设置为 public static final String DEFAULT_NAME = "TIANCI"; int DEFAULT_AGE = 18; String DEFAULT_SEX = "男"; //javaSE8可以有静态方法 static void printSex() { System.out.println(DEFAULT_SEX); }; //javaSE8 可以为接口方法提供默认实现,default进行标记 default void printName() { System.out.println(DEFAULT_NAME); }; }
接口PersonHobby
/** * @version $Id: PersonHobby.java, v 0.1 2017年6月9日 下午5:41:59 */ public interface PersonHobby { String DEFAULT_HOBBY = "运动"; default void printName() { System.out.println("hobby name is:" + DEFAULT_HOBBY); } }
类Person
/** * Person类实现了两个接口,两个接口中都有默认的实现方法printName() * 造成冲突,解决冲突的办法就是在类中覆盖这个方法 * 方法具体实现可以是重写,也可以选择调用具体接口的默认实现方法 * @version $Id: Person.java, v 0.1 2017年6月9日 下午5:19:00 */ public class Person implements PersonInfo, PersonHobby { private String age; private String name; { age = "age init from Person."; name = "name init form Person."; } @Override public void printAge() { System.out.println(age); } //两个接口都有该方法默认实现,进行覆写来解决冲突 //方法具体实现可以是重写,也可以选择调用具体接口的默认实现方法 public void printName() { /*调用具体的接口默认实现 PersonInfo.super.printName();*/ /* 调用具体的接口默认实现 PersonHobby.super.printName();*/ System.out.println(name); } }
测试代码
/** * @version $Id: Test.java, v 0.1 2017年6月9日 下午5:45:44 */ public class Test { public static void main(String[] args) { Person person1 = new Person(); //可以使用接口声明变量,变量必须引用实现了接口的类对象 //但对象的能力只拥有声明的接口类型中的能力 //如person3和person4没有printAge()的能力 PersonInfo person2 = new Person(); PersonHobby person3 = new Person(); PersonHobby person4 = person1; person1.printName(); person1.printAge(); System.out.println("-------"); person2.printName(); person2.printAge(); System.out.println("-------"); person3.printName(); person4.printName(); /* * 对象的能力只拥有声明的接口类型中的能力 * person3和person4没有printAge()能力,下面方法不可用 * person3.printAge(); * person4.printAge(); */ //使用接口调用接口中声明的静态方法 System.out.println("----接口中静态方法---"); PersonInfo.printSex(); System.out.println("----访问接口中常量---"); System.out.println(PersonInfo.DEFAULT_AGE); System.out.println(PersonInfo.DEFAULT_NAME); System.out.println(PersonInfo.DEFAULT_SEX); System.out.println(PersonHobby.DEFAULT_HOBBY); } }
测试结果:
name init form Person. age init from Person. ------- name init form Person. age init from Person. ------- name init form Person. name init form Person. ----接口中静态方法--- 男 ----访问接口中常量--- 18 TIANCI 男 运动
热门文章
- JAVA多线程之同步容器&并发容器
- PHP重载
- 零宽断言正则表达式替换方案
- 「1月24日」最高速度20.3M/S,2025年Shadowrocket/V2ray/Clash/SSR每天更新免费订阅地址分享
- jar包在linux下读取resources下文件
- 「1月14日」最高速度20.8M/S,2025年SSR/Shadowrocket/V2ray/Clash每天更新免费订阅地址分享
- 「1月18日」最高速度20.3M/S,2025年Clash/Shadowrocket/SSR/V2ray每天更新免费订阅地址分享
- Springboot连接MySQL数据库
- 如何在MySQL中使用复合INTERVAL单元?
- 小猫养多久才知道自己的名字了呢(幼猫养多久能知道主人叫它)