接口
接口(interface)用来描述类应该做什么,而不指定它们具体该如何做。一个类可以实现(implement)一个或多个接口。
1. 接口的概念
接口不是类,而是对希望符合这个接口的类的一组需求
Tip
- 接口中的所有方法都自动是
public
,因此在接口中声明方法时,不必提供关键字public
- 接口绝不会有实例字段
public class Employee implement Comparable<Employee> {
// blablabla
@Override
public int compareTo(Employee other) {
return Integer.compare(salary, other.salary);
}
}
2. 接口的属性
接口不是类,不能够使用new
实例化一个接口,但是可以声明接口的变量,接口变量必须引用实现这个接口的类对象
Comparable x = new Employee(. . .);
Tip 为什么需要接口,而不是直接使用抽象类? 因为Java不支持多继承,所以每个类只能扩展一个类。 而接口提供了多继承的好处,而避免了多重继承的复杂性和低效性。
3. 接口与回调
回调(callback)是一种常见的程序设计模式。在这种模式中,可以指定某个特定事件发生时应该采取的动作。比如我们设计了一个时钟,可以请求每秒更新一次,以便更新时钟的表盘。
下面是一个定时器和动作监听的具体使用的例子,定时器启动之后,程序将弹出一个消息对话框,并等待用户点击OK来终止程序的运行,在程序等待用户操作的同时,每隔1秒显示一次当前时间
import java.awt.*;
import java.awt.event.*;
import java.time.*;
import javax.swing.*;
public class TimerTest
{
public static void main(String[] args)
{
TimePrinter listener = new TimePrinter();
// construct a timer that calls the listener
// once every second
Timer timer = new Timer(1000, listener);
timer.start();
// keep program running until the user selects "OK"
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}
class TimePrinter implements ActionListener
{
@Override
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is "
+ Instant.ofEpochMilli(event.getWhen()));
Toolkit.getDefaultToolkit().beep();
}
}
4. Comparator接口
如果我们想要对字符串数组进行排序,可以直接使用String.compareTo
方法按字典顺序比较字符串。 如果我们希望按照字符串长度来进行比较,可以自己实现一个比较器(comparator),如下面的例子中,将比较器作为参数传入Arrays.sort
方法中。
import java.util.Arrays;
import java.util.Comparator;
public class LengthCompare {
public static void main(String[] args) {
String[] friends = {"Adam", "Ben", "Peter", "Noah"};
Arrays.sort(friends, new LengthComparator());
System.out.println(Arrays.toString(friends));
}
}
class LengthComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
}
- 《Java核心技术 卷I》
参考: