接口
1.什么是接口
关键字:规则、扩展、多继承
接口是对类功能的一种扩展, 也是声明规则的一种方式;
接口(interface)是抽象方法和常量值的定义的集合;
1.定义:接口与接口之间是继承关系
interface Inter [extends Inter2, Inter3] {
}
2.实现:先继承类,后实现接口 ——先写extends,后写implements
- 一个类可以实现多个接口,接口也可以继承其它接口
class InterImp extends ClassA implements Inter {
}
3.抽象类—>共性的东西:模板
接口—> 扩展的规则:标准
2.接口存在的意义与作用
接口的出现打破了Java中只支持单继承的局限性,是对类的一种扩展:
- 接口和类之间的关系是实现关系, 可以单实现, 也可以多实现.
3.接口的特性
特点:
1.成员方法:接口中所有的方法默认为 public abstract 方法
2.成员属性:接口中所有的属性默认为 public static final 变量。
3.接口中没有构造器
4.接口是否可以创建对象——不可以的
5.接口用来弥补类无法实现多继承的局限。采用多继承机制
6.接口也可以用来实现解耦???
7.实现类可以实现多个接口,同时可以有自己的父类
- 需要实现这个多个接口中以及其所有上级的全部抽象方法
public interface Runner {
int ID = 1;
void start();
public void run();
void stop();
}
//等价与
public interface Runner {
public static final int ID = 1;
public abstract void start();
public abstract void run();
public abstract void stop();
}
应用 :
- 作为父接口出现 子类(实现类)
- 类和类的关系是 继承 extends 单继承
- 类和接口的关系是 实现 implements 多实现
- 接口和接口之间的关系是 继承 extends 多继承
接口用法总结:
- 通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
- 通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
- 接口主要用来定义规范。解除耦合关系。
案例:
4.JDK1.8 接口静态方法和默认方法
Java 8中,你可以为接口添加静态方法和默认方法。
从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
-
1.静态方法:使用 static 关键字修饰。
接口中定义的静态方法,只能通过接口进行调用,并执行其方法体。
我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类
public static void method4(){ System.out.println("这是接口中静态的方法"); }
-
2.默认方法:使用default 关键字修饰。可以定义共性方法(类似于抽象类的方法),但还保留了多继承的优势;
1)默认方法使用 default 关键字修饰。可以通过实现类对象来调用。
是否需要重写???
2)我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法
public interface AA {
double PI = 3.14;
//默认方法
public default void method() {
System.out.println("北京");
}
default String method1() {
return "上海";
}
//静态方法
public static void method2() {
System.out.println(“hello lambda!");
}
}
java8 中接口的新规定总结:
- ① 接口中可以定义静态方法、默认方法;
- ② 静态方法调用:接口中定义的静态方法,[只能]通过接口进行调用,并执行其方法体;
- ③默认方法调用: 通过实现类的对象,调用接口中的默认方法;
- ④类与接口方法重名: 如果类实现的接口和继承的父类中,定义了同名同参数的方法,那么子类在没重写此方法的情况下,默认调用的是父类中声明的方法。—“类优先”原则;
- ⑤接口与接口方法重名: 如果实现类实现了多个接口,接口中定义了同名同参数的方法。那么此时对于实现类来讲,会出现接口冲突问题:
- 要求实现类必须重写接口中的方法;
- ⑥ 如何在实现类的方法中调用接口中的默认方法——对比③
- CompareA.super.method2();
- ⑦(1)类实现接口以后,要么实现接口中的所抽象方法,方可实例化;
(2)要么当前类声明为抽象类(因为内部包含从接口中获取的抽象方法); - ⑧ 类可以继承多个接口,接口也可以继承接口,一定程度上解决了类的单继承性;接口与接口之间可以多继承也可以单继承;
- ⑨ 接口与具体的实现类之间存在多态性;实际上,接口定义了一套相应功能的[规范与标准]。实现类与对象之间的多态性体现;
注意事项
接口定义时,
-
方法定义:只能是 default[默认方法] abstract[抽象方法] static[静态方法] 中的一个修饰
1)必须是public的(JDK9增加私有方法)
2)默认是abstract,且不可以有方法体;
3)default,static 需要有大括号以及方法体(JDK8增加) -
属性定义:默认是public static final 修饰,也只能是常量;
能不能是私有? 不管什么修饰,都是静态常量么???
5.JDK1.9 接口新增功能
增加了私有方法:供接口内的默认方法调用/(默认方法中存在一些共性的内容)——静态方法在对象加载之前存在
private void init(){
}
6.接口与抽象类之间的关系
7.面向接口编程思想
8.接口默认方法的“类优先”原则
若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时:
- 1)选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
- 2)接口冲突。如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么实现类必须覆盖该方法来解决冲突
接口冲突的解决方式:
问题: 接口到底有没有继承Object类
接口没有继承Object类, 但是接口底层会有Object类所有方法的引用:所以,可以使用多态的形式调用Object类的方法
目的: 就是为了防止多态调用方法的编译报错!