欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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可以省略
      • 因为接口是标准,不需要提供具体的实现,只说有什么行为方法即可,实现交给实现类来做。
      • 例如:学生行为规范中,不能规定学生必须走路上学
  • 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:也可以自己重写
  • 名称解释:

    • 方法签名 = 方法头
    • 方法 = 方法头 + 方法体
    • 方法头/方法签名:【修饰符】 返回值类型 方法名(【形参列表】)
    • 方法体:{方法体}
  • 我们调用/重写时,只要看方法签名就可以。

3、接口还可以继承接口

  • 标准之间可以继承。还是考虑到代码的复用和扩展。
  • 【修饰符】 interface 子接口 extends 父接口们{
    }
  • Java中类与类之间只支持单继承,即只有一个亲生父亲
  • 类与接口之间支持多实现,即你可以有很多个干爹。
  • 接口与接口之间支持多继承,即你可以在多个的行为标准基础上指定新的标准。
interface MyRunnable1{

}
interface MyRunnable2{

}
interface MyRunnable3 extends MyRunnable1,MyRunnable2{

}
相关标签: 接口