Java关于接口
本篇文章的主要内容关于Java的接口。
在《Java核心技术卷》中,这部分的内容稍显混乱,笔者第一次阅读时感觉不知所云,想了半天应该怎么写这篇文章。
为了条例更加清晰,这里从以下几个方面来阐述接口 :
- 接口基本概念
- 接口示例
- 接口的应用场景(与抽象类的差别)
接口基本概念
接口的基本使用
使用接口,要先声明,再实现。
声明接口
1
2
3
4
5
6//声明一个Comparable接口,但没有实现
public interface Comparable<T>
{
//接口中的方法自动声明为public
int compareTo(T other) ; // parameter has type T
}实现接口
实现接口通常有两个步骤 :
将类声明为实现给定的接口(使用关键字 implements:)
1
class Employee implements Comparable
对接口中的所有方法进行定义。
1
2
3
4
5
6//注意 ,实现接口的时候要声明public (和声明接口不同)
public int compareTo(Object otherObject)
{
Employee other = (Employee) otherObject;
return Double ,compare(sal ary, other,sal ary);
}
接口是什么?
接口是
对类的一组需求描述。
一系列方法的声明
是一些方法特征的集合
一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口不是
- 类。(类是使用class关键字定义的,接口是使用interface定义的)
- 抽象类 。(接口不是类,自然也不是抽象类。这里单独提出来的原因是,可以将接口看成没有实例域的抽象类)
接口特性
- 接口不是类,尤其不能使用 new 运算符实例化一个接口
- 接口可以被扩展
- 接口中不能包含实例域或静态方法,但却可以包含常量。
接口示例
这里是一个使用定时器接口的示例。
在 java.swing 包中有一个 Timer 类,可以使用它在到达给定的时间间隔时发出通告,即可以使用Timer类构造定时器。
构造定时器时,我们通常需要一些参数,比如在A秒之后做B事,这个A、B就需要传给定时器。
下面是定时器的接口:
1 | public interface ActionListener |
在 Java 标准类库中的类采用的是面向对象方法,所以将参数传给定时器的方法是将某个类的对象传递给定时器,然后,定时器调用这个对象的方法。
(面向过程的话,就是提供一个函数名, 定时器周期性地调用它。)
因此,定时器需要知道调用对象的哪个方法,并且对象所属的类实现了java.awt.event 包的 ActionListener 接口。
当到达指定的时间间隔时,定时器就调用 actionPerformed 方法。
假设希望每隔 10 秒钟打印一条信息“ 11111111111”, 然后响一声。需要做到事情是
- 应该定义一个实现类
- 上面定义的类要实现ActionListener 接口
- 然后将需要执行的语句放在 actionPerformed方法中。
- 构造这个类的一个对象, 并将它传递给 Timer 构造器。
- 启动定时器
1 | package timer; |
接口的应用场景
前面提到,接口可以看成没有实例域的抽象类。那为什么要有接口?如何选择使用接口或抽象类?
因此抽象类和接口的主要区别汇总如下 :
Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类的优点吧。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。
但是,一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。这是Java抽象类的缺点
在这一点上,Java接口的优点就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。
1 | class Employee extends Person implements Comparable,Runnable // OK |
使用场景
接口可以用来定义契约行为,也可以充当两个系统之间的契约来进行交互
而抽象类主要用于定义子类的默认行为,这意味着所有子类都应该执行相同的功能。
抽象类 :
- 定义某个领域的固有属性,也就是本质
- 当需要为一些类提供公共的实现代码时,应优先考虑抽象类 。因为抽象类中的非抽象方法可以被子类继承下来,使实现功能的代码更简单。
- 如果基本功能在不断变化,使用抽象类(否则每个实现接口的类中都要做出一些更改)
- is-a的关系 ,例如学生和人,巴士和交通工具
接口:
定义某个领域的扩展功能。
想实现多继承时,可以用接口解决。
like-a的关系,A like a B,那么B就是A的接口。 即例如手机属于通讯工具,手机is通讯工具。但是随着技术进步,手机居然能玩游戏了,这显然不是通讯工具有的功能。另外也有手表、汽车等都能新增了玩游戏的功能了,那就可以做一个“玩游戏”接口。手机like玩游戏、手表like玩游戏、汽车like玩游戏。