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

74.接口

程序员文章站 2022-04-29 09:39:56
...

在Java中,除了可以使用抽象类来实现一定程度的抽象外,还可以定义一种特殊的“抽象类”----接口(interface)。

 

接口是方法声明和常量值的定义的集合。在抽象类中,有些方法被实现,而有些方法只有方法的声明,没有方法的具体实现(抽象方法),而在接口中,所有的方法都没有被实现。和抽象类中的抽象方法不一样,这些没有被实现的方法不需要加上关键字abstract来将它声明为抽象方法。

 

接口的定义

 

和类定义不同,接口的定义不使用关键字“class”,而是用另外一个关键字“interface”,接口定义的基本格式如下:

<modifier> interface <name>[extends <superinterface>] {

[<attribute_declarations>]

[<abstract_method_declarations>]

}

 

在接口中,也可以定义属性,但它的成员属性都会被自动加上public、static和final,而对于接口中的方法,也会自动将它设置为public的。虽然我们可以显式的在属性前面加上public static final来修饰它,或者在方法定义前加上public来修饰,但在Java编程规范中,并不推荐这样做。

 

我们来看一个接口的定义。

 

public interface VideoDevice {

public int MIN_BRIGHTNESS = 10;


void turnOn();


void turnOff();

}

 

在这个接口中,定义了一个接口属性:MIN_BRIGHTNESS,用来表示最小亮度;定义了两个方法:用于表示开机的trurnOn()和用于表示关机的turnOff()。在前面我们说过,接口的属性将会被自动加上public static final修饰,所以,我们写一个应用程序来验证它:

 

源文件:TestVideoDevice.java

public class TestVideoDevice {

public static void main(String[] args) {

System.out.println(VideoDevice.MIN_BRIGHTNESS);

}

}

 

在这个类的main()方法中,直接使用“接口.属性名称”来访问接口的方法,我们将它编译并运行,将向控制台打印出如下的信息:

10

 

它就是接口中我们定义的属性“MIN_BRIGHTNESS”的值。从中也可以看出,接口的属性确实已经被加上了“public static”关键字。

 

那么,如何验证它还被自动加上了“final”关键字呢?很简单,只需要在TestVideoDevice的main()方法中写一条语句,试图修改MIN_BRIGHTNESS的值,看看会发生什么结果就可以了:

VideoDevice.MIN_BRGHTNESS = 100;

 

重新编译这个程序,将会出现如下的错误:

TestVideoDevice.java:5: cannot assign a value to final variable MIN_BRIGHTNESS

                VideoDevice.MIN_BRIGHTNESS = 100;

                           ^

1 error

 

很显然,属性MIN_BRIGHTNESS确实已经被加上了“final”修饰符。

 

接口的继承

接口和类类似,也可以从一个父接口中派生。接口的继承也是使用“extends”关键字来完成。

 

接口继承的基本语法如下:

<modifier>  interface  <name> 

[ extends <super_interface> ,<super_interface>]{

[<attribute_declarations>]

[<abstract_method_declarations>]

}

 

和类继承类似,继承的接口也具有了父接口的特性。和类的继承不同的是,在接口的继承中,可以继承多个接口,只需要将继承的各个接口用逗号“,”隔开就可以了

下面我们来看一个接口继承的例子。

 

假设我们需要定义一个视听设备,它应该同时具有可视化设备VideoDevice的特性,又有可发声设备AudioDevice的特性,我们就可以将这个视听设备同时继承VideoDevice和AudioDevice:

 

在前面的例子中,我们已经定义了VideoDevice接口,所以,在这里我们还需要定义一个AudioDevice接口:

 

 

public interface AudioDevice {

public int MIN_VOLUME = 5;


void turnOn();


void turnOff();


void tuneVolume(int volume);

}

 

然后,我们来定一个接口“AVDevice”,让它同时继承接口“VideoDevice”和“AudioDevice”:

 

public interface AVDevice extends VideoDevice,AudioDevice{

void shiftChannel();

}

 

除了从“AudioDevice”和“VideoDevice”继承的方法外,在这里新增了一个方法:shiftChannel()。

 

现在,我们可能会对Java中的继承方式会有了更深的了解:所谓Java不支持多继承,指的是不支持类的多继承

 

使用接口

 

对于抽象类,我们在子类中用“extends”来继承它。但是,对于接口,在子类中必须要用另外一个关键字“implements”来“实现”它

 

一个“实现”了接口的类,必须将它实现的接口中的方法都实现,或者,将没有实现的方法定义为抽象的方法,此时,类也必须定义为抽象类。

 

类实现接口的语法格式如下:

<modifier>  class  <name>  [ extends <superclass> ]

[implements  <interface>  [,<interface>]* ] {

<declarations> *

}

 

在Java中,一个类只能继承一个父类,也就是说,Java不支持多继承。但是,一个类可以实现多个接口。通过接口,可以模拟实现多继承

 

一个类可以继承一个父类,并且同时实现一个或多个接口。在多个接口之间用“,”来分割开。

 

我们来看一个实现接口的例子。

 

interface Metal{

public void twinkle();

}

 

在这里定义了一个“金属”的接口:Metal,在这个接口中,有一个方法:twinkle(),用来表示金属的闪光光泽。

源文件:Substitution.java

interface Substitution{

public void exchange();

}

这里定

义的是一个“交换物”的接口,这个接口只声明了一个方法:exchange(),用来表示等价交换。

 

 

public class Gold implements Substitution, Metal {

/**

 * 实现Substitution的exchange()方法

 */

public void exchange() {

System.out.println("Exchange");

}


/**

 * 实现Metal中的方法

 */

public void twinkle() {

System.out.println("Shining");

}


public static void main(String args[]) {

Gold gold = new Gold();

gold.exchange();

gold.twinkle();

}

}

 

然后我们定义了一个“黄金”类用来表示黄金这个实体。黄金同时具有“金属”和“等价交换物”的特点,在这边我们同时实现了“Metal”和“Substitution”这两个接口,然后,在这个类中将两个接口中的方法实现。这样,就实现了“多继承”的功能。

 

提示:

实现接口的时候必须在实现的方法前面加上public,这是因为在接口中默认的方法修饰符是public。