接口
在java5中,Comparable接口已经提升为一个泛型类型。
package chapter_6;
import java.time.LocalDate;
public class Employee implements Comparable<Employee> {
private String name;
private double salary;
private LocalDate hireDay;
/* public int compareTo(Object otherObject)
{
Employee other=(Employee)otherObject;
return Double.compare(salary,other.salary);
}*/
public int compareTo(Employee other)
{
return Double.compare(salary,other.salary);
}
public Employee() {
}
public Employee(String name, double salary, int year, int month, int day) {
this.name = name;
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public void setHireDay(LocalDate hireDay) {
this.hireDay = hireDay;
}
@Override
public String toString() {
return "polymorphic_my{" +
"name='" + name + '\'' +
", salary=" + salary +
", hireDay=" + hireDay +
'}';
}
}
接口中所有方法都是public
package chapter_6;
import java.util.Arrays;
public class EmployeeSortTest {
public static void main(String[] args) {
var staff=new Employee[3];
staff[0]=new Employee("文天瑞",100,2003,5,12);
staff[1]=new Employee("谢雨晨",1000,2002,4,3);
staff[2]=new Employee("黄颖琪",10000,2004,6,7);
Arrays.sort(staff);
for (Employee employee : staff) {
System.out.println("name="+employee.getName()+" ,salary="+ employee.getSalary());
}
}
}
package chapter_6;
import java.time.LocalDate;
public class Employee implements Comparable<Employee> {
private String name;
private double salary;
private LocalDate hireDay;
/* public int compareTo(Object otherObject)
{
Employee other=(Employee)otherObject;
return Double.compare(salary,other.salary);
}*/
public int compareTo(Employee other)
{
return Double.compare(salary,other.salary);
}
public Employee() {
}
public Employee(String name, double salary, int year, int month, int day) {
this.name = name;
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public void setHireDay(LocalDate hireDay) {
this.hireDay = hireDay;
}
@Override
public String toString() {
return "polymorphic_my{" +
"name='" + name + '\'' +
", salary=" + salary +
", hireDay=" + hireDay +
'}';
}
}
接口的属性
接口变量必须引用实现了这个接口的类对象例如:
Comparable x=new Employee(...);
静态和私有方法
在java8中,允许在接口中增加静态方法,通常是将静态方法放在伴随类中。
在java9中,接口中的方法可以是private。
默认方法
可以为接口方法提供一个默认实现。必须用default修饰符标记这样一个方法。
package chapter_6;
public interface my_Comparable<T> {
default int compareTo(T other){return 0;}
}
默认方法可以在Iterator接口中有用,例如:
package chapter_6;
public interface Iterator <E>{
boolean hasNext();
E next();
default void remove(){throw new UnsupportedOperationException("remove");}
}
如果我的迭代器是只读的,就不用操心实现remove方法。
解决默认方法冲突
1.超类优先,如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
2.接口冲突。如果一个接口提供了一个默认方法,另一个接口提供了一个相同的方法,必须覆盖这个方法来解决冲突。
例如:
package chapter_6;
public interface Person {
default String getName(){return "1";}
}
interface Named
{
default String getName(){return getClass().getName()+" "+hashCode();}
}
class Student implements Person,Named{
public String getName()
{
return Person.super.getName();
}
public static void main(String[] args) {
Student student=new Student();
System.out.println(student.getName());
}
}
接口和回调
package chapter_6;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;
public class TimerTest {
public static void main(String[] args) {
var listener =new TimePrinter();
var timer=new Timer(100,listener);
timer.start();
JOptionPane.showMessageDialog(null,"Quit progrem?");
System.exit(0);
}
}
class TimePrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone,the time is"+ Instant.ofEpochMilli(event.getWhen()));
Toolkit.getDefaultToolkit().beep();
}
}
方法引用
例如:
var timer=new Timer(1000,System.out::println);
表达式System.out::println就是一个方法引用,编译器会根据上下文来确定使用哪一个方法。
例如:
Arrays.sort(planets,String::compareToIgnoreCase);
注意,只有当lambda表达式只调用一个方法而不做其他操作时,才能把lambda表达式重写为方法引用。