1.注意事项
1.接口中的所有方法自动的属于public,因此在接口中声明方法时,不必提供关键字public。
2.可以在接口中提供简单的方法、常量,但是在接口中不能定义实例域(接口中的域将自动设置为public static final
),可以将接口看成没有实例域的多继承的抽象类。
3.如果子类之间的比较含义不一样,那就属于不同类之间的非法比较。如果存在一种通用的方法,能够对两个不同子类的对象进行比较,则应该在超类中提供compareTo方法,并且将这个方法声明为final。
4.接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性。
5.在Java SE 8中允许在接口中增加静态方法(只是这有违于接口作为抽象规范的初衷)。目前通常的做法都是将接口的静态方法放在伴随类中(e.g. Collection/Collections或Path/Paths)。在Java SE 8之后,可以直接在接口中提供静态方法,从而取消伴随类。
6.接口中的默认方法可以进行接口演化,为接口增加一个非默认方法,不能保证源代码兼容。将方法实现为默认方法,就可以保证接口扩展后不会出现源代码不兼容、编译出错的问题。
7.解决默认方法冲突问题:
如果先在一个接口中将一个方法定义为默认方法,然后又在超类或者另外一个接口中定义了同样的方法,需要按照以下规则保证执行哪一个方法:
1)超类优先:如果超类提供了一个具体的方法,同名且具有相同参数的默认方法会被忽略;
2)接口冲突:如果一个接口提供一个默认方法,另一个接口提供相同的方法,必须覆盖这个方法来解决冲突。
8.Comparator接口
Comparator接口是一个比较器接口,对于已经继承Comparable接口的类,我们如果不想按照类设定的规则进行排序比较,那么就需要继承Comparator接口,定义自己的比较规则。
public interface Comparator<T>{
int compare(T first,T second);
}
compare方法不是静态方法,使用时需要建立对象来调用。
9.对象克隆
Employee original = new Employee("John Public",50000);
Employee copy = original;
copy.raiseSalary(10);
以上代码,copy对象的改变会引起original的改变。如果希望copy是一个新对象,它的初始状态与original相同,但是希望之后它们有各自的状态,这种情况下就可以使用clone方法。
Employee original = new Employee("John Public",50000);
Employee copy = original.clone();
copy.raiseSalary(10);
以上代码copy的改变不会引起original的改变。
e.g.
package clone;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* @author feng
* @create 2021-04-02 18:16
*/
public class Employee implements Cloneable {
private String name;
private double salary;
private Date hireDay;
public Employee(String name,double salary){
this.name = name;
this.salary = salary;
hireDay = new Date();
}
public Employee clone() throws CloneNotSupportedException {
//call object.clone()
Employee cloned = (Employee) super.clone();
//clone mutable fields
cloned.hireDay = (Date) hireDay.clone();
return cloned;
}
public void setHireDay(int year,int month,int day){
Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime();
hireDay.setTime(newHireDay.getTime());
}
public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;
salary += raise;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary=" + salary +
", hireDay=" + hireDay +
'}';
}
}
package clone;
/**
* @author feng
* @create 2021-04-02 18:29
*/
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
Employee original = new Employee("JOhn Public", 50000);
original.setHireDay(2000, 1, 1);
Employee copy = original.clone();
copy.setHireDay(2002, 12, 31);
copy.raiseSalary(10);
System.out.println("original=" + original);
System.out.println("copy=" + copy);
}
}
original=Employee{name='JOhn Public', salary=50000.0, hireDay=Sat Jan 01 00:00:00 CST 2000}
copy=Employee{name='JOhn Public', salary=55000.0, hireDay=Tue Dec 31 00:00:00 CST 2002}