zoukankan      html  css  js  c++  java
  • 答网友强护灰飞烟灭关于接口的问题

    经我努力找,终于在

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

     

     

     

  • 相关阅读:
    迭代器在LinkedList上的删除
    java多线程:CopyOnWriteArrayList
    vs中代码编译通过,但还是有红色波浪线
    vs中项目属性配置
    TortoiseGit安装与配置
    DC(device context)
    weak_ptr 使用
    C++ 中shared_ptr循环引用计数问题
    for_each与lambda表达式联合使用
    new 和 make_shared 在内存上的区别
  • 原文地址:https://www.cnblogs.com/CCQLegend/p/3307968.html
Copyright © 2011-2022 走看看