再议java接口的使用
接口我认为表示的是一种功能,一旦一个类实现了这个接口,就可以认为该类就具备了这种功能。由于接口具备的这种能力,所以在实际应用中,我们一般利用接口来制定标准
为什么可以利用接口来制定标准,我们可以想一下,我们在上文中说了,一旦一个类实现了一个接口,我们就可以认为该类具备了某一种功能。而不同的类都依据这个接口来实现了相同的功能,我们可以认为这样就制定了标准。在执行标准的时候会先通过是否实现了该共功能的接口来判断是否执行(这里还可以看出接口有一种标识的功能)
举一个例子,USB接口在我们实际生活中经常被运用,电脑的USB接口一般可以插入优盘 鼠标 或手机等等。之所以可以这样操作,USB有个标准,只有实现了该标准才能被插入。我们的优盘 鼠标或手机实际上在其内部上都实现了该标准(相当于代码中implements USB),然后再电脑上使用时会先根据你是否实现了USB接口来判断你是否实现了该标准,然后决定是否准许你的接入
以USB接口实例说明
//用接口定义标准
interface USB{
public abstract void start();//工作开始
public abstract void stop();//工作停止
}
//打印机实现USB接口
class Print implements USB{
public void start(){
System.out.println("打印机开始工作....");//覆写
}
public void stop(){
System.out.println("打印机停止工作....");//覆写
}
}
class Flash implements USB{
public void start(){
System.out.println("U盘开始工作.....");//覆写
}
public void stop(){
System.out.println("U盘停止工作.....");//覆写
}
}
class Computer{
//工作开始,只有符合USB接口标准的才可以工作
public void plugin(USB usb){
usb.start();//开始工作
System.out.println("工作进行中l......");
usb.stop();//工作停止中
}
}
public class InterfaceTest{
public static void main(String[]args){
new Computer().plugin(new Print());//插入打印机
new Computer().plugin(new Flash());//插入U盘
}
}
output:
打印机开始工作....
工作进行中l......
打印机停止工作....
U盘开始工作.....
工作进行中l......
U盘停止工作...
这是我们自己编写的接口,直接是上java官方了实现了很多接口,让一些了去实现,让其具备一些功能,Comparable和Comparator就是其中的2个,从字面上也可以看出,他们应该是想让实现他们的类具备比较功能
**问题引出:在Arrays类中有一个sort方法,可以实现数组的排序,当传入double int float..数组都没有问题,我就在想能不能传入一个对象数组,根据对象的某些属性给对象进行排序,但是悲剧出现了,
package com.cn;
import java.util.Arrays;
class Books{
private String name;
private float price;
public Books(String name,float price){
this.name=name;
this.price=price;
}
public String toString(){
return "图书名称:"+this.name+"图书价格:"+this.price+"\n";
}
}
public class ArraysTest {
public static void main(String[] args) {
Books books[] = {
new Books("java编程思想", 23.3f),
new Books("java宝典", 34.2f), new Books("java", 45.5f)};
System.out.println(Arrays.toString(books));
Arrays.sort(books);//ClassCastException
}
}
其中异常提示里面有这么一句: Test.Books cannot be cast to java.lang.Comparable
- Comparable接口
定义方式:Interface Comparable
通过看API文档我们可以知道java中定义的大量的类都实现了Comparable接口,即我们可以知道java中很多的类都可以支持类中对象的比较,此处将Comprable接口定义成泛型接口可以使得我们的程序更加安全,因为大量的类都实现了这个接口,而对于对象的比较实际上是对该类所有属性的比较,所以不可避免的要进行向下转型工作,如此处理不当将出现ClassCastException,而将接口定义成泛型,在定义接口时直接指定泛型类型,完全可以避免这个问题
而从上面的例子我们知道,这个接口相当于只是告诉我们有这个标准,而对于具体的标准我们需要自己来实现,如果是java自己定义的类,应该都实现好了,但是如果是我们自己定义的类,这个标准就只能我们自己 手动去实现了
分析到这里我们大致可以分析出sort函数的工作原理了,它可以实现对大量类型数组的排序的前提是该类型实现了Comprable接口并且在该接口的子类中实现排序的标准,而sort函数底层实现应该就相当于上文Computer类中的那个函数一样,会先判断该类型是否实现了这个接口然后执行相应的操作,框架和前面的举例因该差不多。而实现对基本数据类型的数组的排序,应该是装箱成类然后进行的。(有很多个人的猜想,如果有误请指出)
package Test;
import java.util.Arrays;
class Book implements Comparable<Book> {
private String name;
private float price;
public Book(String name, float price) {
this.name = name;
this.price = price;
}
public String toString() {
return "图书名称:" + this.name + "图书价格:" + this.price + "\n";
}
//覆写接口里面的抽象方法
public int compareTo(Book b) {
if (this.price > b.price) {
return 1;
} else if (this.price < b.price) {
return -1;
} else {
return 0;
}
}
public static class ArraysTest {
public static void main(String[]args){
Book book[] = {
new Book("java编程思想", 35.3f),
new Book("java宝典", 28.2f), new Book("java", 45.5f)};
System.out.println(Arrays.toString(book));
Arrays.sort(book);//ClassCastException
System.out.println(Arrays.toString(book));
}
}
}
output:
原数组:
[图书名称:java编程思想图书价格:35.3
, 图书名称:java宝典图书价格:28.2
, 图书名称:java图书价格:45.5
]
排序后数组:
[图书名称:java宝典图书价格:28.2
, 图书名称:java编程思想图书价格:35.3
, 图书名称:java图书价格:45.5
]
可以看到按照价格的升序进行排序了
可以看到,我们在设计这个Book类的时候就就想到了比较的需求,但是如果我们以前设计的类中没有设计比较,而现在需要比较那该该怎么办,需要一个类一个类的更改吗?其实我们java也提供了另外一种比较器可以适应这种场景,这里不详细讲解