带接口的泛型方法的边界类型参数?

时间:2015-06-02 15:01:09

标签: java generics methods interface generic-method

所以我有两个版本的相同方法。

版本1:

public static <T> int countGreaterThan(T[] anArray, T elem) 
    {
        int count = 0; 
        for (T e : anArray)
        {
            if (e > elem)
                count++;
        }
        return count;
    }

版本2:

public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem)
    {
        int count = 0;
        for (T e : anArray)
        {
            if (e.compareTo(elem) > 0)
                count++;
        }
        return count;
    }

Eclipse抱怨版本1 ,因为&gt;运算符只能在比较基元时使用,这对我来说很有意义。

所以为了解决这个问题,互联网告诉我要使用一个由Comparable接口限定的类型参数。这是我开始忘记正在发生的事情......

根据我对接口的基本理解,实现接口的类必须为接口中声明的每个方法提供一个方法体。

因此,为什么版本2 必须看起来像这样?

public int compareTo(T o)
    {
        //stuff for method body
    }


    public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem)
    {
        int count = 0;
        for (T e : anArray)
        {
            if (e.compareTo(elem) > 0)
                count++;
        }
        return count;
    }

^ 我认为这不是正确的语法,但我只是为了说明我的问题,为什么我不必为Comparable接口中的方法编写方法体在这种情况下。

请尽量按照Layman的说法保留解释。我一直在教自己这些东西,所以当我进一步研究它们时,简单的解释可以帮助我理解主题的技术方面。

对于这种困惑感到抱歉,让我澄清一下。

以下是Comparable接口的代码:

public interface Comparable<T> {
   public int compareTo(T o);
     }

compareTo()没有方法体,因为它是一个接口。为什么我不必为compareTO()手动编写一个主体,所以我可以在countGreaterThan()方法中使用该接口?

是否因为接口是Java Collections Framework的一部分(如果这就是为什么请解释它是如何工作的)

这是我创建自己的界面的另一种情况:

public interface Dance { //an interface
  public void boogie(int count);
}

为了在不同的类中实现该接口,我需要在舞蹈界面中为方法编写方法体。

public class theMoonwalk implements Dance {
  public void boogie(int count) {
    System.out.println("Slide " + count + " times!");
  }
  public void mJ() {
    System.out.println("Michael Jackson did this dance!");

}
public class theHustle implements Dance {
  public void boogie(int steps) {
    System.out.println("Step " + steps + " times!");
  }
}
public class theJitterBug implements Dance {
  public void boogie(int twists) {
    System.out.println("Twist " + twists + " times!");
  }
}

为什么我不必为compareTo()编写方法体(因为compareTo()的Comparable接口中没有包含方法体?)

1 个答案:

答案 0 :(得分:3)

T最终引用的类型必须实现Comparable<T>,而不是您声明绑定类型的类。

为了使它更简单:为了使用countGreaterThan方法,数组中包含的任何对象和elem参数中的对象必须是Comparable对象。

这意味着可以接受这样的调用:

Integer[] foo = {1, 2, 3, 4, 5};
YourClass.countGreaterThan(foo, 2);

您的类型绑定到IntegerInteger implements Comparable<Integer>

可以接受:

Object[] bar = {new Object(), new Object(), new Object()};
YourClass.countGreaterThan(bar, new Object());

您的类型绑定到Object,而Object未实现Comparable。相同的逻辑适用于您实现的自定义对象;如果它不与Comparable绑定,那么它就不会处于适当的范围内。