接口
/*
Arrays.sort方法可以对对象数组进行排序,但要求满足前提:对象所属的类必须实现Comparable接口
调用 x.compareTo(y)
x<y return negative number
x=y return 0
x>y return positive number
*/
public interface Comparable{
int compareTo(Object other);
}
//java se 5.0+ Comparable interface has type T
public interface Comparable<T> {
int compareTo(T other); //parameter has type T
}
接口属性
- 接口中的方法自动且必须属于public
- 接口不能含有实例域
- javase8之前,接口不能实现方法
接口实现
- 将类声明为实现给定的类,class ${className} implements ${interface1,interface2…}
- 对接口中的所有方法进行定义 已提供默认实现的方法也需要进行定义吗?
class Employee implements Comparable{
private double salary;
public int compareTo(Object otherObject){
Employee other = (Employee)otherObject;
return Double.compare(salary, other.salary);
}
}
package interfaces;
import java.util.*;
public class EmployeeSortTest{
public static void main(String[] args){
Employee[] staff = new Employee[3];
staff[0] = new Employee("xx", 1000);
staff[1] = new Employee("yy", 2000);
staff[2] = new Employee("zz", 3000);
Arrays.sort(staff); //mergesort
for (Employee e : staff) {
System.out.prinfln("name=" + e.getName() + ",salary=" + e.getSalary());
}
}
}
package interfaces;
//泛型接口
class Employee implements Comparable<Employee>{
private String name;
private double salary;
public Employee(String name, double salary){
this.name = name;
this.salary = salary;
}
public String getName(){
return name;
}
public double getSalary(){
return salary;
}
public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;
salary += raise;
}
@override
int compareTo(Employee other){
return Double.compare(salary, other.salary);
}
}
接口不是类,不能用new实例化接口,即不能构建接口对象,但能声明接口变量。
Comparable x;
接口变量必须引用实现了该接口的类对象。
x = new Employee(…); //Employee implements Comparable
instanceof
- 检查一个对象是否属于特定类
- 检查一个对象是否实现特定接口
- if (anObject instanceof Comparable)
接口可以扩展,从较高通用性的接口到较高专用性的接口的链
接口不允许实例域,但允许常量 自动为 public static final
public interface Powered extends Moveable{
double milePerGallon();
double SPEED_LIMIT = 95; // a public static final constant
}
抽象类的方法也是不写实现的,为什么不用抽象类包装方法,而使用接口呢?
- 类只能继承一个父类,但能实现多个接口
extends 1 implements more
abstract class Comparable{
public abstract int compareInt(Object other);
}
javase 8以后,接口允许增加静态方法
- 好处:不再需要写伴随类(实现接口的类)
- 坏处:违背接口作为抽象规范的初衷
有很多成对出现的接口和工具类,如Collection/Collections, Path/Paths, 在接口中写静态方法,可以不再需要伴随类
//Path写方法实现,不需要Paths
public interface Path{
public static Path get(String first, String ... more){
return FileSystems.getDefault().getPath(first, more);
}
}
默认方法
可以为接口方法提供一个默认实现,使用default修饰符
该方法的实现会覆盖这个方法,但也可以不在实现类中写该方法的实现?
public interface Comparable<T>{
default int compareTo(T other){
return 0;
}
}
默认方法的重要作用是“接口演化”(interface evolution),对接口新增方法,写了默认实现就无需操心实现类是否能正常编译。
关于默认方法冲突:超类、接口有同名且同参数的默认方法
- 超类优先
- 接口冲突,程序员必须解决二义性,否则无法编译
class Student implements Person, Named{
public String getName(){
return Person.super.getName();
}
}
// 即使其中一个接口(假设是Named)的getName方法并不是默认方法,Student类也不会直接从Person继承默认方法,还是需要程序员解决二义性冲突
因为超类优先的原则,同时我们知道Object类是所有类的超类,所以不要让默认方法重新定义Object类中的方法,例如.toString()或.equals,因为无法超越Object中的默认实现,是无效的。
回调,callback,常见程序设计模式,指出某个特定事件发生时应该采取的动作。