答网友强护灰飞烟灭关于接口的问题
经我努力找,终于在
java.util.Collections
处找到了这么一个方法:
static <T>int binarySearch(List<? extends Comparable<? super T>> list, T key);
什么意思呢?就是在一个List里要进行搜索一个元素key,并返回其在此List的索引。
上面这个东东太复杂?没事,我给你一个个分解:
static <T>int binarySearch(List<T> list, T key);
但这就有一个问题,binarySearch顾名思义,就是二分搜索,要在一组排好序的List里找出元素key,因为是二分搜,所以不可能从头一个个遍历,要涉及到两两进行比较。
如果一个List是1,2,3,4,5,6,7,8,那好比较,1<2<3……。
但是要是我一个自定义类呢?比方说我定义一个class A,那我把一个List<A>类型的list传给binarySearch函数吗?显然,一般情况下不行,因为你没定义A的对象与对象之间该如何比较大小。所以binarySearch限制你传进去的List<A>的A的类型。
于是就有以下约束:
static <T>int binarySearch(List<? extends Comparable<T>> list, T key);
那么String实现了Comparable接口,那么
List<String> a=new ArrayList<String>();//我就不往里添加元素了。 Collections.<String>binarySearch(a,"a");//OK,String实现了Comparable接口,可以互相比较。
假设你整了一个A类:
class A
那么:
List<A> a=new ArrayList<A>();//我就不往里添加元素了。 Collections.<A>binarySearch(a,new A());//Error,A没实现Comparable接口,不知如何互相比较。
那你在整一个自定义类:
class B implements Comparable<B>
List<B> a=new ArrayList<B>();//我就不往里添加元素了。 Collections.<B>binarySearch(a,new B());//OK,B实现了Comparable接口,可以调用ComparTo方法比较两个元素的大小。
所以,这里的关键是,允许你传的List<T>类型的T是自定义的类,而不是JAVA自定义好的如String类。那么,我就不用非要局限除了极少数String的List可以进行二分搜索以外,其他统统不能用。binarySearch方法只需要规定你的那个T类型,任何已经实现了Comparable接口,都可以进行二分搜索,而不管你是哪个类所继承的Comparable接口,也不管这个接口如何被使用。
还有不懂?
再看下面,二分搜索binarySearch方法里,首先第一个就是把key和List中间的那个元素进行比较。详细如下:
1 static <T>int binarySearch(List<? extends Comparable<? super T>> list, T key) 2 { 3 int index=list.size();//返回list的元素的个数。 4 T t=list.get(index/2);返回list的中间的那个元素。 5 //然后这就有问题了,T是什么类型,你这里能够预先知道么?显然不知道。那你怎么让一个不知道是什么类型的两个元素进行比较?很简单,T是Comparable接口的子类,那么我一定能保证t一定有一个成员叫ComparTo方法。 6 int result=t.ComparTo(key);//调用ComparTo方法让t与key比较。 7 //根据Comparable接口的约定,ComparTo方法规定了返回结果大于0,则t>key;等于0,那么t=key;如果小于0,则t<key。至于实现这个接口的,是String,还是上面提到的自定义类B,抑或是还有未知的类型,我管得着么?我需要管么?只要有了Comparable接口,我就能秒杀一切实现此接口的类。 8 //后面的还怎么比较我就不列举了。 9 }
三句话总结:接口就是约定一组对象的成员方法,但我不知道这个对象是什么类的对象,也不知道这个类怎么实现这个方法。但只要这个类有继承此接口,此对象一定会有我要的方法。我的目的只需要保证这个对象有我需要的方法,就OK了,管他是谁家的对象呢?
=============================================================我是分界线===================================================
理论上第一次回答就已经给出interface的实例了,不知道网友你是没看呢还是怎么样。我再把举过的例子整理一遍。
interface IShape//这跟Comparable接口相似 { double CalculateArea();//IShape接口之定义了方法名和形参列表,并没有定义怎么实现 } class Square implements IShape { //其他成员我就不写了。 public double CalculateArea() { return a*a; } } class B//你可能有疑问,我继承一个IShape,什么功能都没得到,我继承这个接口干什么?不继承了! { public double CalculateArea()//我不需要继承IShape也能定义CalculateArea方法啊! { return a*a; } } class Util { public static void F(IShape s) { …… double result=s.CalculateArea();//我Util类管你实现的类是什么类?只要你是IShape的子类,我就能调用! …… } } class Test { public static void main(String[] args) { Square sq=new Square(); Util.F(sq);//能传参数。最关键的是,我无论自定义一个什么类,只要都是继承于IShape接口,就可以作为实参调用F方法。 B b=new B(); Util.F(b);//Error!人家F方法哪知道你B类是个什么类?你不继承IShape接口,我如何保证你真的定义了一个符合我要求的CalculateArea方法了?你定义了我也不知道,没法调用啊! } }