泛型接口

除了泛型类和泛型方法之外,接口也可以是泛型的.泛型接口的指定方式和泛型类相似.下面的示例创建了一个泛型接口Containment,他可以由保存一个或多个值的类实现.他声明了一个方法contains()来判断调用对象是否包含指定的值.
public class test2
{
    public static void main(String args[])
    {
     Integer x[] = {1,2,3};
     
     MyClass<Integer> ob = new  MyClass<Integer>(x);
     
     if(ob.contains(2))
         System.out.println("2 is in ob");
     if(ob.contains(5))
         System.out.println("5 is in ob");
    }
}
interface Containment<T>
{
    boolean contains(T o);
}
class MyClass<T> implements Containment<T>
{
    T[] arrayRef;
    
    MyClass(T[] o)
    {
        arrayRef = o;
    }
    
    //implements contains()
    public boolean contains(T o)
    {
        for(T x:arrayRef)
            if(x.equals(o)) return true;
        return false;
    }
}
输出如下所示:
2 is in ob
尽管该程序的大多数地方容易理解,但还是有两点需要指出.首先,注意containment使用如下语句声明:
interface Containment<T>
一般而言,泛型接口与泛型类的声明方式相同.在本例中,类型形参T指定所包含的对象的类型.接下来,containment由MyClass实现,注意声明MyClass语句:
class MyClass<T> implements Containment<T>
一般而言,如果一个类实现了泛型接口,那么该类也必须是泛型的,至少他接受传递给接口的类型形参,在本例中,标识符T是未知的,编译器将报告出错,当然,如果一个类实现泛型接口的特定类型,如下所示:
class MyClass implemetns Containment<Double>
那么实现接口的类则不必是泛型的.你可能会猜到,泛型接口指定的类型形参也可以被约束,这样做可以限制接口能够实现的数据类型,例如,如果想把containment限制为数值类型,可以这样声明接口:
interface containment<T extends Number>
现在,任何实现该接口的类都必须向containment传递一个也具有相同约束的类型实参,例如,现在MyClass必须这样来声明:
class MyClass<T extends Number> implements Containment<T>
要特别注意MyClass声明类型形参T,然后把他传递给Containment的方式,由于Containment现在需要扩展Number类型,因此实现接口的类(MyClass)也必须指定相同的约束.而且,一旦建立了约束,就不需要在implements子句中再次指定他,实际上这样做会出错,例如下面的声明就不正确:
class MyClass<T extends Number> implements Contaiment<T extends Number>