接口
- 一.对学生进行排序
- 二.Clonable接口
- 三.抽象类和接口的区别
- 四.Object类
一.对学生进行排序
很明显我们直接对学生进行排序是会报错的,因为编译器也不知道你需要按照名字排还是分数排,我们点击报错位置进入sort内部。
在sort内部我们可以看到它把数组转换成立一个Comparable类型。而这个Comparable是一个接口型,而这个接口里有一个compareto方法,我们需要实现这个接口。
import java.util.Arrays;class Student implements Comparable<Student>{String name;int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "Student{" +"name=" + name +", score=" + score +'}';}@Overridepublic int compareTo(Student o) {if(this.score<o.score) return 1;else if(this.score>o.score) return -1;else return 0;}
}public class sort {public static void main(String[] args) {Student[] st=new Student[3];st[0]=new Student("张三",28);st[1]=new Student("李四",100);st[2]=new Student("王麻子",63);Arrays.sort(st);//排序System.out.println(Arrays.toString(st));//打印出来}
}
但是这样写有一个很明显缺点,就是写死了。它这个类就只能按年龄比较,为了更加灵活,java又提供了另一个接口comparator。
import java.util.Arrays;
import java.util.Comparator;class Student{String name;int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "Student{" +"name=" + name +", score=" + score +'}';}
}//灵活方法
class Scompare implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {if(o1.score<o2.score) return 1;else if(o1.score>o2.score) return -1;else return 0;}
}public class sort {public static void main(String[] args) {Student[] st=new Student[3];st[0]=new Student("张三",28);st[1]=new Student("李四",100);st[2]=new Student("王麻子",63);//使用Scompare s=new Scompare();Arrays.sort(st,s);//排序System.out.println(Arrays.toString(st));//打印出来}
}
二.Clonable接口
Java 中内置了一些很有用的接口, Clonable 就是其中之一
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”。但是要想合法调用 clone 方法, 必须要先实现Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。object是所有类的父类(即使你没有写任何继承)。
import java.util.Arrays;
import java.util.Comparator;class Student implements Cloneable{String name;int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "Student{" +"name=" + name +", score=" + score +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class sort {//因为克隆会抛出一个异常,所以main函数也需要声明异常public static void main(String[] args) throws CloneNotSupportedException{Student A=new Student("张三",60);//因为克隆方法是object里的,object是所有类的父类//这里相当于向下转,所以需要强转转型Student B=(Student) A.clone();System.out.println(B);}
}
上面我们仅仅是调用的object的克隆方法会问题,更改一下代码
这里出现了问题,我们只对A的money进行了修改,就跟B的money也发生了改变,不符合我们的预期。
因为我们仅仅将A里Money类的地址进行了拷贝,所以两者指向的Money对象自然是同一个,接下来实现一下让他们指向不同Money。
import java.util.Arrays;
import java.util.Comparator;class Money implements Cloneable{public double money=12.5;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}class Student implements Cloneable{public String name;public int score;public Money m=new Money();public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "Student{" +"name=" + name +", score=" + score +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {//克隆了student对象Student stu=(Student) super.clone();//克隆了student里的money对象stu.m=(Money) this.m.clone();return stu;}
}
public class sort {//因为克隆会抛出一个异常,所以main函数也需要声明异常public static void main(String[] args) throws CloneNotSupportedException{Student A=new Student("张三",60);//因为克隆方法是object里的,object是所有类的父类//这里相当于向下转,所以需要强转转型Student B=(Student) A.clone();System.out.println(A.m.money);System.out.println(B.m.money);System.out.println("#########");A.m.money=52.2;System.out.println(A.m.money);System.out.println(B.m.money);}
}
三.抽象类和接口的区别
核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法,子类必须重写所有的抽象方法。
四.Object类
Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。
例如
所以在开发之中,Object类是参数的最高统一类型。但是Object类也存在有定义好的一些方法。如下:
例如为什么在写了toString后printlen就会自动调用toString呢
printlen实际上是用object类接收的,然后再调用了一个valueof。
而valueof也是用object类接收,它就会调用自己写的toString。