学习Java第十九天--接口回调案例
接口回调是使用Java接口的一种思想,理解其有助于Java编程
接口回调的意思是,在使用接口时,最先定义接口,然后由程序员先编写接口的使用者,再编写接口的实现者,最后通过接口的调用者来使用功能;
我们通过一个案例来理解接口回调:
平时我们排序都是对数组中的数进行排序,比如:使用Java提供的java.util.Arrays.sort();方法对数组进行降序排序。
但如果我们需要对自己定义的学生类数组进行排序,Java提供的方法无法排序,因为学生类有很多属性,它不知道你需要按照什么规则进行排序。
那么你需要一个工具来帮助你排序,最好是无论是什么类型的数据都可以进行排序。
首先,我们来定义一个接口来规定排序的方法:
/*
* 接口/标准(排序)
* 只有现实此接口的对象,才可以排序
* */
public interface Comparable<T> {
/*
* 比较的方法
* this与传入的stu对象进行比较
* @param stu 另一个学生对象
* @return 标准:正数 负数 零
* 负数:this靠前,stu靠后
* 正数:this靠后,stu靠前
* 零:不变
* */
public int compareTo(T stu);//Student stu
}
我们定义了这样一个接口,它里面只定义了一个比较的方法,它会接收一个数据类型,并通过返回整数来表示比较结果;
然后,有了接口,我们接下来要写一个拥有这个接口标准的排序工具,我们可以通过这个工具对任意类型的数据进行排序;
/*
* 排序工具
* 可以帮助任何类型的一组对象做排序
* */
public class Tool {//接口的使用者
public static void sort(Student[] stus) {
for(int j = 0; j < stus.length ; j++) {//使用冒泡排序对数据进行排序
for(int i = 0 ;i < stus.length - j - 1; i++) {
Comparable currentStu = (Comparable)stus[i]; //接口引用指向强转的接口对象,确保该对象拥有接口方法(接口标准)
int n = currentStu.compareTo(stus[i+1]); //调用接口定义的方法进行比较,通过返回值,得到比较结果
if(n > 0) {
Student temp = stus[i];
stus[i] = stus[i+1];
stus[i+1] = temp;
}
}
}
}
}
我们将工具写好了,如果只看这个工具,似乎看不出来我们的比较规则,因为我们还没有编写接口的实现者,接口的实现类规定了比较的规则,只要比较的规则确定了,那么这个工具就可以对传进来的数据进行排序;
class Student implements Comparable<Student>{//接口的实现者
String name;
int age;
String sex;
double score;
public Student() {}
public Student(String name, int age, String sex, double score) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
}
public int compareTo(Student stu) {//这里编写了比较的规则
if(this.score > stu.score) {//只要从这里修改规则,就可以做到对其的任意属性进行排序
return 1;
}else if(this.score < stu.score) {
return -1;
}
return 0;
}
}
这里我们将学生类实现接口类,可以定义比较规则,那么只要我们在主函数中定义数据,并调用工具,就可以完成对学生类的排序了。
public class TestCallback {
public static void main(String[] args) {
//需求:对一组学生对象排序
Student[] students = new Student[] {
new Student("tom",20,"male",99.0),
new Student("jack",21,"male",95.0),
new Student("alex",20,"male",100.0),
new Student("annie",19,"female",97.0),
};
//java.util.Arrays.sort(students);
//工具调用者
Tool.sort(students);
for(int i = 0 ; i < students.length ; i++) {
System.err.println(students[i].name+"\t"+students[i].score);
}
}
}
运行结果如下,将学生类按成绩降序进行了排序:
其实我们写的Comparable接口Java中有,而我们经常使用的java.util.Arrays.sort();排序方法就相当于我们刚刚写的工具,它是Comparable接口的使用者;
假如我们直接使用java.util.Arrays.sort();方法对学生类进行排序:
public class TestCallback {
public static void main(String[] args) {
Student[] stus = new Student[]{
new Student("tom",99D),
new Student("jack",95D),
new Student("jane",100D),
new Student("annie",97D)
};
java.util.Arrays.sort(stus);//Java提供的sort方法,升序,本来是无法为Student类型进行排序,通过实现接口,使其可以排序
for(int i = 0 ; i < stus.length ; i++) {//Student对象的遍历
System.out.println(stus[i].name +"\t"+stus[i].score);
}
}
}
class Student implements Comparable<Student>{//实现Comparable接口
String name;
double score;
public Student() {}
public Student(String name , double score) {
this.name = name;
this.score = score;
}
public int compareTo(Student s) {//实现接口方法
if(this.score > s.score) {
return 1;
}else if(this.score < s.score) {
return -1;
}else{
return 0;
}
}
}
因为Java本身就有接口和工具,那么我们只需要实现接口,制定比较方法,就可以实现排序,同样,只要我们对实现接口方法进行修改,任意类型的任意排序方法都可以实现。这里也是接口回调,接口是一开始就定义好的;工具是根据接口来编写的;当接口和接口的使用者都存在后,才会出现接口的实现者。实现者通过接口的使用者,即可以完成功能。