Java接口
程序员文章站
2022-03-04 13:37:03
...
什么是接口?
-
接口: ==> 行为标准
-
生活中:
-
电脑的接口:USB接口
-
电源的插座接口:两个和三个眼
-
因为生产电脑的厂商,无法给各种其他硬件都提供不同的插口,只能统一标准,你想要和电脑相连,进行数据传输,那么只能遵循我的USB接口标准。
-
同样的,插座的厂商,无法给各种电器提供不同的插口,只能统一标准,你想要使得你的电器充电,只能按照我的标准来。
-
-
Java中:
-
当我们需要设计一组类:
- (1)这些类具有相同的“行为特征”(方法)时,
- (2)而且这组类又不属于同一个类型,即它们之间除了Object没有其他公共的父类。
- (3)每一个类对这个“行为特征”(方法)的实现又不同
- 那么我们可以把这样的“行为特征”(方法)抽取到接口中,以便统一管理它们。
-
特别是后面,JDBC(Java连接数据库的技术):
- 数据库的产品:oracle,mysql,sql server, DB2,redis,mango DB, sqllite…
- 所以为了保证我们(1)Java程序员不需要学习n套API(2)Java代码可以“跨平台”,那么我们需要制定一套标准,都是接口。
- 这些接口中都是“抽象方法”,它们的实现交给各个数据库厂商,那么我们开发时,只要把这些数据库厂商实现接口的类(驱动)拿过来就可以。
-
接口(标准)、实现类(遵循这个标准给出的具体的实现)
-
在我们的代码中就可以面向接口编程,即编译时按照接口类型处理,当驱动类(实现类)加入进来后,运行的是实现类的代码。
-
1、如何声明和实现接口?
- 【修饰符】 interface 接口名{
} - 【修饰符】 class 实现类 implements 接口们{
} - 要求:如果实现类不是抽象类,那么实现类必须实现接口的所有的抽象方法。
- 说明:一个类可以同时实现多个接口
public class TestInterface {
public static void main(String[] args) {
Flyable[] arr = new Flyable[3];
arr[0] = new Bird();
arr[1] = new Kite();
arr[2] = new Plane();
for (int i = 0; i < arr.length; i++) {
arr[i].fly();
}
}
}
interface Flyable{
public abstract void fly();//抽象方法
}
class Bird implements Flyable{
public void fly(){
System.out.println("扇动翅膀飞");
}
}
class Kite implements Flyable{
public void fly(){
System.out.println("绳子拽着飞");
}
}
class Plane implements Flyable{
public void fly(){
System.out.println("靠螺旋桨飞");
}
}
2、接口中都可以有什么成员?
-
1.JDK1.8之前:
-
(1)公共的静态的常量: 其中public static final可以省略
- 因为接口是标准,那么接口中定义的数据就要写死。
- 例如:8.25分进班,这个时间点必须固定。
-
(2)公共的抽象的方法: 那么其中public abstract可以省略
- 因为接口是标准,不需要提供具体的实现,只说有什么行为方法即可,实现交给实现类来做。
- 例如:学生行为规范中,不能规定学生必须走路上学
-
(1)公共的静态的常量: 其中public static final可以省略
-
JDK1.8之后:
-
对接口进行了修改,在原来的基础上,接口增加了两类成员:
-
(3)公共的静态的方法:
- 因为JDK1.8之前,接口中不允许出现静态方法时,有很多关于操作接口及其实现类对象的工具类的API需要单独一个类来表示:
- 例如:Collection接口系列,会有一个工具类Collections,Path接口,会有一个工具类Paths…
- 这样设计了,API的类型的数量增多了。增加维护的成本和程序员的负担。
- 因此这样的方法,JDK1.8之后,就干脆就直接在接口中声明了。
- 调用类中的静态方法: A:类名.静态方法 B:对象.静态方法
- 调用接口中的静态方法: 接口名.静态方法(注意)
-
(4)公共的默认的方法:
- A:之前如果某个接口,在它的某些实现类中的实现是一样的,那么这样的实现就可以抽取到接口中,用默认方法来表示。至于其他不一样实现的实现类又可以选择“重写”
- B:之前已经设计好的某些接口,在JDK1.8及其之后,需要在接口中新增方法。如果按照之前,只能增加抽象方法。那么一旦给一个已经存在时间很长的接口增加一个抽象方法,会导致它原来所有的实现类都要对这个抽象方法进行实现。所以,这个影响面就太大了。
- DK1.8之后允许有默认方法之后,对于之前的接口要增加新方法的话,就可以增加默认方法,原来的实现类,如果需要更新,那么可以重写这个默认方法,如果不更新,编译也可以正常通过,不影响原来的功能。
-
-
2、 默认方法的语法格式:
-
public default 返回值类型 方法名(【形参列表】){ //这里public可以省略,但是不能写其他修饰符
哪怕什么也没写,这个{}也不能省略
} -
强调:default单词是在接口中要写的,在实现类中进行重写时,这个default就不要再写了。
-
-
3、如何调用默认方法
- 只能通过“实现类的对象.方法"进行调用
-
4、默认方法的冲突问题
- (1)当一个实现类同时实现了多个接口,此时多个接口中出现了“签名相同”的默认(用default的)方法,那么实现类必须做出选择
- A:保留A
- B:保留B
- C:都不要
- (2)当一个实现类同时继承了父类,又实现了接口,当接口中与父类中出现了“签名相同”的方法(注意,这里说的是方法,如果是同名成员变量将没有默认保留,如果不表名具体是谁的,那么就会编译报错)
- A:默认保留的是父类的
- B:也可以选择接口的
- 接口名.super.方法
- C:也可以自己重写
- (1)当一个实现类同时实现了多个接口,此时多个接口中出现了“签名相同”的默认(用default的)方法,那么实现类必须做出选择
-
名称解释:
- 方法签名 = 方法头
- 方法 = 方法头 + 方法体
- 方法头/方法签名:【修饰符】 返回值类型 方法名(【形参列表】)
- 方法体:{方法体}
-
我们调用/重写时,只要看方法签名就可以。
3、接口还可以继承接口
- 标准之间可以继承。还是考虑到代码的复用和扩展。
- 【修饰符】 interface 子接口 extends 父接口们{
} - Java中类与类之间只支持单继承,即只有一个亲生父亲
- 类与接口之间支持多实现,即你可以有很多个干爹。
- 接口与接口之间支持多继承,即你可以在多个的行为标准基础上指定新的标准。
interface MyRunnable1{
}
interface MyRunnable2{
}
interface MyRunnable3 extends MyRunnable1,MyRunnable2{
}