当前教程
接口
系列中的下一个

系列中的下一个: 实现接口

接口

 

Java 中的接口

在软件工程中,存在许多情况,需要不同编程组之间达成“契约”,明确规定其软件如何交互。每个组都应该能够编写自己的代码,而无需了解其他组代码的编写方式。一般来说,接口就是这样的契约。

例如,想象一个未来社会,计算机控制的机器人汽车在没有人类操作员的情况下将乘客运送到城市街道。汽车制造商编写软件(当然是用 Java)来操作汽车——停止、启动、加速、左转等等。另一个工业集团,电子制导仪器制造商,制造接收 GPS(全球定位系统)位置数据和交通状况无线传输的计算机系统,并使用这些信息来驾驶汽车。

汽车制造商必须发布一个行业标准接口,详细说明可以调用哪些方法来使汽车移动(任何汽车,来自任何制造商)。然后,制导制造商可以编写软件,调用接口中描述的方法来控制汽车。这两个工业集团都不需要知道对方软件的实现方式。事实上,每个组都认为自己的软件是高度专有的,并保留随时修改其软件的权利,只要它继续遵守已发布的接口。

在 Java 编程语言中,接口是一种引用类型,类似于类,它只能包含常量方法签名默认方法静态方法(私有或公共,而不是受保护的)、实例非抽象方法(私有,而不是公共,而不是受保护的)和嵌套类型。方法体仅存在于默认方法、私有方法和静态方法中。接口不能被实例化——它们只能由类实现或由其他接口扩展。扩展将在本节后面讨论。

定义接口类似于创建新类

public interface OperateCar {

   // constant declarations, if any

   // method signatures
   
   // An enum with values RIGHT, LEFT
   int turn(Direction direction,
            double radius,
            double startSpeed,
            double endSpeed);
   int changeLanes(Direction direction,
                   double startSpeed,
                   double endSpeed);
   int signalTurn(Direction direction,
                  boolean signalOn);
   int getRadarFront(double distanceToCar,
                     double speedOfCar);
   int getRadarRear(double distanceToCar,
                    double speedOfCar);
         ......
   // more method signatures
}

请注意,方法签名没有大括号,并以分号结尾。

要使用接口,您需要编写一个实现该接口的类。当一个可实例化的类实现一个接口时,它会为接口中声明的每个方法提供一个方法体。例如,

public class OperateBMW760i implements OperateCar {

    // the OperateCar method signatures, with implementation --
    // for example:
    public int signalTurn(Direction direction, boolean signalOn) {
       // code to turn BMW's LEFT turn indicator lights on
       // code to turn BMW's LEFT turn indicator lights off
       // code to turn BMW's RIGHT turn indicator lights on
       // code to turn BMW's RIGHT turn indicator lights off
    }

    // other members, as needed -- for example, helper classes not 
    // visible to clients of the interface
}

在上面的机器人汽车示例中,汽车制造商将实现该接口。当然,雪佛兰的实现将与丰田的实现大不相同,但两家制造商都将遵守相同的接口。制导制造商(接口的客户)将构建使用 GPS 数据来确定汽车的位置、数字街道地图和交通数据的系统来驾驶汽车。在这样做的过程中,制导系统将调用接口方法:转向、变道、刹车、加速等等。

 

接口作为 API

机器人汽车示例展示了接口作为行业标准应用程序编程接口 (API) 的使用。API 在商业软件产品中也很常见。通常,一家公司会出售一个包含复杂方法的软件包,另一家公司希望在其自己的软件产品中使用这些方法。一个例子是数字图像处理方法包,这些方法被出售给制作最终用户图形程序的公司

  • 图像处理公司编写其类来实现一个接口,并将其公开给客户。
  • 然后,图形公司使用接口中定义的签名和返回类型来调用图像处理方法。

虽然图像处理公司的 API 是公开的(面向其客户),但其 API 的实现被视为严格保密的——事实上,它可能会在以后修改实现,只要它继续实现其客户依赖的原始接口。接口是通用的引用类型,允许您定义default方法并向给定类型添加功能,而不会破坏实现类。此外,有时您可以在private方法中提取公共代码段,从而减少default方法中的代码重复。查看本系列中的下一个教程,以了解有关接口中方法定义的更多信息。

 

定义接口

接口声明由修饰符、关键字interface、接口名称、逗号分隔的父接口列表(如果有)和接口体组成。例如

public interface GroupedInterface extends Interface1, Interface2, Interface3 {

    // constant declarations
    
    // base of natural logarithms
    double E = 2.718282;
 
    // method signatures
    void doSomething (int i, double x);
    int doSomethingElse(String s);
}

public访问说明符表示该接口可以被任何包中的任何类使用。如果您没有指定接口是公共的,那么您的接口只能被与接口定义在同一个包中的类访问。

接口可以扩展其他接口,就像类可以子类化或扩展另一个类一样。但是,类只能扩展一个其他类,而接口可以扩展任意数量的接口。接口声明包含一个逗号分隔的列表,其中包含它扩展的所有接口。

接口体可以包含抽象方法、默认方法和静态方法。

接口中的抽象方法后面跟着分号,但没有大括号(抽象方法不包含实现)。

默认方法使用default修饰符定义,静态方法使用static关键字定义。接口中的所有抽象方法、默认方法和静态方法都是隐式公共的,因此您可以省略public修饰符。

此外,接口可以包含常量声明。接口中定义的所有常量值都是隐式publicstaticfinal。再次,您可以省略这些修饰符。


上次更新: 2024 年 1 月 5 日


当前教程
接口
系列中的下一个

系列中的下一个: 实现接口