🎇个人主页:Ice_Sugar_7
🎇所属专栏:快来卷Java啦
🎇欢迎点赞收藏加关注哦!
抽象类&接口2
- 🍉接口间的继承
- 🍉接口的应用
- 🍉总结
🍉接口间的继承
和类的继承一样,接口之间存在继承的关系,不过我们叫作拓展
,就是说一个接口在另一个接口的基础上,拓展了其他功能。接口的拓展也是使用关键字extends
public interface A {void test1();
}public interface B extends A{void test2();
}public class TestDemo1 implements B{@Overridepublic void test1() { //需要重写接口A中的方法}@Overridepublic void test2() {}
}
接口间的拓展相当于把多个接口合并为一个接口
🍉接口的应用
有了接口,我们可以给对象数组
(数组元素是一个个对象)排序
- Comparable接口
public class Student implements Comparable<Student>{private String name;private int grade; //学生成绩
}
比如要给学生类排序,给出一个学生类的数组,我们希望按照成绩进行排序
Arrays
类中的sort方法
可供我们对数组元素排序
但是sort只能对内置类型进行排序,因为两个内置类型变量的大小关系是明确的。而对于学生类,两个学生对象的大小关系是需要我们自己指定的,即我们自己确定比较的标准
那怎么确定标准呢?这就需要我们的 Student 类实现 Comparable
接口, 并实现其中的compareTo
方法
Comparable接口
是Java自带的接口,实现时需要在后面加上<类类型>
,表示这个类型可以进行比较,其中这个“类类型”表示我们想要进行比较的类型
public class Student implements Comparable<Student> {//...
}
public class Student implements Comparable<Student>{private String name;private int grade;public Student(String name, int grade) {this.name = name;this.grade = grade;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", grade=" + grade +'}';}@Overridepublic int compareTo(Student o) { //compareTo方法的形参类型是Object,不过使用idea生成时,会自动调整为你要比较的类型if(this.grade > o.grade) {return 1;} else if (this.grade == o.grade) {return 0;} else {return -1;}}
}
那对于这样一组数据:
public static void main(String[] args) {Student students[] = new Student[]{new Student("张三", 98),new Student("李四", 99),new Student("王五", 85),new Student("Sugar", 88)};Arrays.sort(students);for (Student student:students) {System.out.println(student);}}
排序后就是:
小结:
- sort 要求传入的数组的每个对象都是“可比较”的,也就是说对象中的某个成员变量可以进行比较(比如姓名、年龄等)。这样通过
重写 compareTo 方法
就可以定义比较规则
不过这种方法是把比较的方法写在类里面,如果原先是按成绩进行排序,现在要改成按姓名或者其他属性比较的话,那就要把整个方法都改了,不太方便
- Comparator接口
Comparator接口中有一个compare方法
:
Arrays的sort方法提供多种重载,其中一个的参数列表是对象数组
和比较器
我们只要实现comparator接口(比较器),重写里面的compare方法就可以进行比较
以对学生成绩排序为例
public class Student{private String name;private int grade;public Student(String name, int grade) {this.name = name;this.grade = grade;}public String getName() {return name;}public int getGrade() {return grade;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", grade=" + grade +'}';}
}public class GradeComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getGrade()- o2.getGrade();}
}public class Main {public static void main(String[] args) {GradeComparator gradeComparator = new GradeComparator();Student[] array = {new Student("张三",98),new Student("李四",99),new Student("王五",85),new Student("Sugar",88)};Arrays.sort(array,gradeComparator);System.out.println(Arrays.toString(array));}
}
使用比较器是在实现比较器的类
中(GradeComparator)重写compare方法,而不是在待比较的对象所属的类(Student)之中
这样就比较灵活,我们想按对象的什么属性来比较排序,就新建一个类,按我们的需求重写compare方法
Moreover,我们可以尝试实现一个sort方法,加深对接口的理解。下面以直接插入排序为例:
public class insertSort {public static void InsertSort(Comparable[] comparables) {for(int i = 0;i < comparables.length - 1;i++) {int end = i;for(int j = end;j >= 0;j--) {if(comparables[j].compareTo(comparables[j+1])>0) {Comparable tmp = comparables[j];comparables[j] = comparables[j+1];comparables[j+1] = tmp;}}}}
}public class Student implements Comparable<Student>{private String name;private int grade;public int compareTo(Student o) { //以grade作为比较排序的标准return this.grade - o.grade;}
}public class Main {public static void main(String[] args) {Student[] students = {new Student("张三",98),new Student("李四",99),new Student("王五",85),new Student("Sugar",88)};insertSort.InsertSort(students); //通过类名调用insertSort类中的方法System.out.println(Arrays.toString(students));}
}
直接插入排序的具体实现可以看这篇文章:「数据结构」八大排序1
🍉总结
- 接口的继承关系——拓展,它可以拓展接口的功能
- 通过重写Comparable接口或Comparator接口下的方法,我们可以实现对象类型的比较