java学习笔记:接口(interface)

接口概述
接口是抽象方法和常量值的定义的集合,从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。

接口纯粹是一种表达方式,而类则是设计和实现的混合体。

接口的声明
接口是通过使用关键字interface,然后给定其命名,并在大括号中列出其接口成员来声明的。

接口可以有三种类型的成员:
(1)常量(域)
(2)方法;
(3)嵌套类和接口。

以下是一个接口定义的例子:

public interface Runner{
int id = 1;
void run();
}

接口中的变量默认是用public static final标识的,所以,接口中定义的变量就是全局静态常量。按照规定,这些修饰符已经被省略掉了,当然,也可以将public static final修饰符加上。

接口中的方法默认是用public abstract 标识的,按照规定,这两个修饰符被省略掉了。因为接口中的方法都是隐式的abstract,所以接口中的方法不能给出任何实现。除此之外,任何其他的方法修饰符均不允许出现在接口的方法声明中。

因为他们是隐式public的,因此就不能有其他的访问修饰符;
因为他们没有被实现,所以不能拥有定义实现特征的修饰符(native、synchronized、strictfp);
因为他们是抽象的,所以不能同时静态的,静态方法不可以是抽象的。

所有的接口成员(域、方法、嵌套类及嵌套接口)都是隐士公共的,但是按照规定,public修饰符被省略掉了。

在接口声明前还可以放置的接口修饰符:

(1)public
被public所修饰的接口可以被公共的访问。如果没有这个接口,接口只能够被其所在包中的成员访问。

(2)abstract
所有的接口都被隐式的定义为abstract的,因为他们的方法都是抽象的,他们没有任何实现。作为约定,abstract修饰符被省略掉了。

(3)
strict floating point
声明为strictfp的接口拥有所有的浮点运算能力。

==========================

接口的继承

我们使用extends继承一个现有的接口。与类不同,接口继承多个接口。

以下是一个示例:

public interface SerializableRunnable extends java.io.Serializable, Runnable{
//….
}

SerializableRunnable接口继承了java.io.Serializable和Runnable接口,这意味着现在由这些接口定义的所有方法、常量和SerializaRunnable中定义的新方法和新常量一起都成为了SerializableRunnable约定的一部分了。被继承的接口是新接口的超接口,新接口是其超接口的子接口。

继承和隐藏常量
继承接口继承了其超接口中声明的所有常量。如果接口中声明了一个和其继承来的常量同名的常量,那么不论他们的类型如何,新常量都会隐藏掉继承常量。即在子接口和任何实现了子接口的对象中,仅使用名字来引用常量将会引用子接口中定义的那个常量。不过,我们任然可以通过使用常量的完全限定名(即接口名.常量名)来获得对继承常量的访问。

继承和覆盖、重载方法
子接口继承了超接口所声明的所有方法。如果子接口中声明的某个方法和继承来的方法拥有相同的签名(名字和参数列表)和相同的返回值类型,那么新的声明会覆盖任何已经存在的方法。

如果某个接口继承了具有了具有相同签名的多个方法,或者某个类实现了包含相同签名的方法的不同接口,那么只会有一个这样的方法存在,它的实现是由实现接口的类所最终定义的,这这种情况下不存在二义性。

==========================

接口实现

我们使用implements来实现一个现有的接口。

以下是一个示例:

package com.darkmi.test;

public interface Runnable {
void run();
}

接口Runnable 表示具有奔跑的能力。

package com.darkmi.test;

public class Dog implements Runnable {

public void run() {
System.out.println(“the dog is running~”);
}
}

类Dog实现了Runnable接口。

==========================

接口与抽象类的区别

接口与抽象类之间有两点重要区别:
(1)
接口提供一种多重继承的方式,因为你可以实现多个接口。类只能继承一个别的类,即使那个类只有abstract方法。

(2)
abstract类可以有部分实现,以及protected部分、static方法等,而接口仅限于未经实现的public方法和常量。

接口通过抽象的约定定义了一个类型,抽象类同样通过抽象的约定定义了一个类型。那么究竟该用哪一个以及何时使用呢?以下是几条参考意见:

(1)
如果多重继承很重要,则使用接口。

(2)
抽象类能够提供部分或者全部的实现,如果你需要这个功能,那么使用抽象类。如果你发现自己所编写的某个抽象类只有抽象方法,那么实际上你所编写的是一个接口。

==========================

2010年4月9日:补充了一个接口实现的示例。

此条目发表在java/j2ee分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据