答网友强护灰飞烟灭关于接口的问题

经我努力找,终于在

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方法了?你定义了我也不知道,没法调用啊!
    }    
}

 

 

 

 

 

posted on 2013-09-08 00:01  CCQLegend  阅读(429)  评论(0编辑  收藏  举报

导航