从零开始学Java Web开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.3 接口

在本章前面的内容中已经介绍过,Java只允许单继承,即不允许一个类同时继承多个父类,不过Java中提供了接口,一个类可以同时实现很多个接口,这样就实现了多重继承的部分功能。

3.3.1 接口的定义

接口的定义包括接口声明和接口体。其定义的一般格式如下:

    [public] interface interfaceName[extends listOfSuperInterface] {
          type methodname(parameterlist);
          type constname=value;
    }

其中,接口只能用public限制访问修饰符修饰,不能使用其他的限制访问修饰符,extends后可以有多个父接口,这多个父接口之间用逗号隔开。

接口体包括常量定义和方法声明,这里的方法声明包含方法名称、参数列表和返回值类型,但是没有方法体。看到这里,读者可能会问,接口不就是抽象类吗?的确,接口与抽象类有许多相同之处,但是它们之间也有很多的不同点。接口与抽象类是属于不同的层次,接口是将抽象类提高了一个层次,并给它加上了一些限制和特性。

下面来比较一下接口与抽象类的异同。

相同点:

❑ 接口与抽象类中都包含有方法声明,这些方法声明将在实现接口或继承抽象类的类中具体实现,否则这些实现接口或继承抽象类的类还是抽象类。这也是容易把接口和抽象类混淆的主要原因。

❑ 接口与抽象类中由于都有方法声明,因此都不能用new来创建对象,但它们都可以去引用实现接口或继承抽象类的类的实例。

❑ 接口与抽象类都可以实现继承,继承之后子接口就拥有了所有父接口中的方法声明和常量定义了,抽象类继承父类后也将用于父类中的所有方法和属性。

不同点:

❑ 在抽象类中,方法声明的前面必须加上abstract关键字,而在接口中则不需要。

❑ 在抽象类中,除了抽象方法之外,也可以定义普通的成员方法和成员变量,而在接口中这是不允许的,接口中只能有方法声明和常量定义,这是接口和抽象类的本质区别。

❑ 接口允许多继承,不但一个接口可以继承多个父接口,而且实现接口的类也可以同时实现多个接口。

【实例3-9】接口的定义。该实例定义一个用于计算立体几何图形体积的接口,因为不同的立体几何图形计算体积的方法不同,因此可以在接口中定义一个计算体积的方法的声明,而在具体的图形类中实现该接口,并根据各图形的体积计算公式来定义该方法。接口的具体定义如下:

    01  public interface ThreeD_Object {
    02          float Volume(float x, float y, float z);//定义接口中的抽象方法
    03  }

【代码说明】在该接口的第2行定义了一个抽象方法Volume。

说明

在接口中只能有方法声明,不能有方法的具体实现。

3.3.2 接口的实现

接口中的方法声明需要在某个类中定义实际的代码,这时我们就称这个类“实现”了这个接口。关键字implements用来表示对接口的实现。如果一个类同时实现了多个接口,则只需在implements后把多个接口名用逗号隔开即可。

接口实现的一般格式如下:

    class <类名> implements <接口名>

例如,下面示例代码中定义了两个接口及实现这两个接口的实现类。

    01  interface A {
    02        void Method1();
    03  }
    04  interface B {
    05        void Method2();
    06  }
    07  class C implements A,B {
    08         public void Method1() {
    09               ……//具体方法定义代码
    10           }
    11  public void Method2() {
    12               ……//具体方法定义代码
    13           }
    14  }

【代码说明】在第8行实现了接口A中的方法,第12行实现了接口B中的方法。

说明

在类中实现接口中的方法声明时,方法的返回值类型、方法名称和参数列表必须保持一致,同时要给出方法的具体实现代码。此外,Java中规定在类中实现的方法都要声明为public的。

如果在实现接口的类中没有定义接口中方法的具体实现,那么在这个类中这个方法就将是一个抽象方法,由于这时它位于类中,那么这个类就将成为抽象类。

【实例3-10】接口的实现。

在实例3-9中定义了用于计算立体几何图形体积的接口,在实例3-10中根据具体立体几何图形分别定义该接口不同的实现类。

首先定义立方体的实现类Cube,具体代码如下:

    01  class Cube implements ThreeD_Object {
    02         //根据立方体体积计算公式具体定义方法
    03         public float Volume(float x, float y, float z) {
    04              return x*y*z;
    05         }
    06  }

【代码说明】在第3行定义了ThreeD_Object接口中声明的Volume()方法,在该方法中具体定义了立方体体积的计算方法。

然后定义圆柱体的实现类Cylinder,具体代码如下:

    01  class Cylinder implements ThreeD_Object {
    02         //根据圆柱体体积计算公式具体定义方法
    03         public float Volume(float x, float y, float z) {
    04              return x*y*y *z;
    05         }
    06  }

【代码说明】在第3行定义了ThreeD_Object接口中声明的Volume()方法。在该方法中具体定义了圆柱体体积的计算方法。

最后定义应用程序类ShowVolume,用来测试实现接口的类,其具体代码定义如下:

    01  public class ShowVolume {
    02      public static void main(String args[]){
    03           float vol1,vol2;
    04           float PI=3.14159f;
    05           ThreeD_Object obj1=new Cube();       //创建Cube类的对象
    06           ThreeD_Object obj2=new Cylinder()    ;//创建Cylinder类的对象
    07           vol1=obj1.Volume(20.0f, 10.0f, 30.0f); //调用Cube类中实现的接口中的方法
    08           vol2=obj2.Volume(PI, 10.0f, 30.0f);  //调用Cylinder类中实现的接口中的方法
    09           System.out.println("The Volume of cube is:"+vol1);
    10           System.out.println("The Volume of cylinder is:"+vol2);
    11      }
    12  }

【代码说明】在应用程序类中的第5行和第6行分别实例化一个Cube类和Cylinder类的实例,然后在第7行和第8行通过这两个实例分别调用了Volume()方法,虽然是同一个方法,但是这两个方法在不同的类中得到了不同的定义。

【运行结果】最终程序输出结果如图3.6所示。

图3.6 接口实现类中具体方法的执行结果