|
注:
关于接口分成两篇文章讲解,☝🏻上篇文章主要讲解使用语法,本篇文章会使用两个常用例子来帮助我们更好的的了解接口。那我们就开始吧~
接口使用实例
1. 自定义类的比较和排序
1.1 比较
我们先写一个学生类:
class Student {
public String name;
public int age;
public double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "[" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
']';
}
}
现在我们有一个 问题 ,如果我们实例化两个student,我们如何比较这两个对象的大小?
# 注意事项 #
再java中对象的引用
之间比较,不可以直接用(>,<,=)
比较,实际比较的是两个对象谁大谁小。
那么到底应该如何比较呢?
这时我们就需要让Student类实现一个接口—— Comparable< T >
我们可以看到里面有一个CompareTo
的抽象方法,我们现在就在Student
类中重写这个抽象方法:
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
这时我们就可以进行比较
了:
public class TestDemo {
public static void main(String[] args) {
Student student1 = new Student("玛卡巴卡",6,34.4);
Student student2 = new Student("依古比古",8,68.2);
if(student1.compareTo(student2) > 0) {
System.out.println(student1.name + "比" + student2.name + "大");
} else {
System.out.println(student1.name + "比" + student2.name + "小");
}
}
}
1.2 排序
现在我们有一个Students
,学生类数组:
public class TestDemo {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("玛卡巴卡",6,34.4);
students[1] = new Student("依古比古",8,68.2);
students[2] = new Student("唔西迪西",7,54.9);
}
}
这里我们使用到Arrays.sort
这样我们就可以通过我们刚刚实现的接口Comparable
来排序,学生数组。
public class TestDemo {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("玛卡巴卡",6,34.4);
students[1] = new Student("依古比古",8,68.2);
students[2] = new Student("唔西迪西",7,54.9);
Arrays.sort(students);
System.out.println("排序后" + Arrays.toString(students));
}
}
1.3 多种依据的比较和排序
我们思考一个 问题 ,如果有的人想要年龄
排序,有的人想要分数
排序,应该怎么办呢?
为了解决这个问题,我们就有了另外一个接口Comparator< T >,叫做"比较器"
我们分别来重写这个compare
方法:
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
class ScoreComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return (int)(o1.score - o2.score);
}
}
这时我们就可以进行比较了,按年龄比较
public class TestDemo {
public static void main(String[] args) {
Student student1 = new Student("玛卡巴卡",6,34.4);
Student student2 = new Student("依古比古",8,68.2);
AgeComparator ageComparator = new AgeComparator();
if(ageComparator.compare(student1,student2) > 0) {
System.out.println(student1.name + "比" + student2.name + "大");
} else {
System.out.println(student1.name + "比" + student2.name + "小");
}
}
}
按成绩比较
public class TestDemo {
public static void main(String[] args) {
Student student1 = new Student("玛卡巴卡",6,34.4);
Student student2 = new Student("依古比古",8,68.2);
ScoreComparator scoreComparator = new ScoreComparator();
if(scoreComparator.compare(student1,student2) > 0) {
System.out.println(student1.name + "比" + student2.name + "成绩好");
} else {
System.out.println(student1.name + "没有" + student2.name + "成绩好");
}
}
}
方法已经重写完了,下面我们用来进行排序:
public class TestDemo {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("玛卡巴卡",6,99.9);
students[1] = new Student("依古比古",8,68.2);
students[2] = new Student("唔西迪西",7,54.9);
Arrays.sort(students,new AgeComparator());
System.out.println("按年龄排序后" + Arrays.toString(students));
Arrays.sort(students,new ScoreComparator());
System.out.println("按分数排序后" + Arrays.toString(students));
}
}
运行结果展示:
# 注意 #
对于 sort 方法来说, 需要传入的数组的每个对象都是 "可比较"
的, 需要具备 compareTo
这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.
2. Clonable接口和深拷贝
我们先创建一个Person类
class Person {
public int age;
public Person(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
我们对于一个现有的person要如何克隆一个呢?
public class TestDemo {
public static void main(String[] args) {
Person person = new Person(18);
}
}
2.1 Cloneable接口
Object
类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现Clonable
接口, 否则就会抛出CloneNotSupportedException 异常.Clonable接口当中没有抽象方法,是一个空接口。 空接口/标记接口:表示当前类可以被克隆。
class Person implements Cloneable{
//·····
}
现在我们需要重写clone
方法:
这个clone方法是重写谁的呢?是Object
的clone方法。
我们再在主函数中处理一下:
这时我们就可以clone一个person了。
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person(18);
Person copy = (Person)person.clone();//返回值的Object类型,需要强制类型转换
System.out.println(copy);
}
}
此时:(这就是一种深拷贝,更改copy中age的值,不会改变person中age的值)
2.2 深拷贝
我们现在增加一个Money
类:
class Money {
public double money;
public Money(double money) {
this.money = money;
}
}
在Person
类中加入这样一行代码:
public Money m = new Money(10.9);
这时我们克隆一个person,更改copy中的money会怎样呢?
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person(18);
Person copy = (Person)person.clone();
System.out.println(person);
System.out.println(copy);
System.out.println("=================");
copy.m.money = 99.9;
System.out.println(person);
System.out.println(copy);
}
}
运行结果展示:
这是为什么呢?
下面我们来画几个图了解一下
此时我们的m是浅拷贝,即改变copy内m.money中的值会影响person中的值。
那么如果我们想实现深拷贝应该怎么做呢?
1.Money类实现Cloneable接口,重写clone方法
class Money implements Cloneable{
public double money;
public Money(double money) {
this.money = money;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
2.更改Person类中的clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
Person tmp = (Person)super.clone();
tmp.m = (Money) this.m.clone();
return tmp;
}
这时我们就实现了深拷贝:
运行结果展示:
|
以上就是今天要讲的内容了,希望对大家有所帮助,如果有问题欢迎评论指出,会积极改正!!下一篇文章会继续讲述Java的相关知识,期待大家支持,谢谢~