如何在java中使用接口作为列表或数组类型?

时间:2015-04-05 20:12:04

标签: java

欢迎所有聪明人,

我对这个主题做了我的研究,我知道它写在某个地方,但我无法在任何地方找到它(但我知道我几周前就读过它了)......所以这是我的问题:

使用Java 8,应该可以在数组或列表中使用接口作为集合类型(不确定哪一个)...是否有人能够告诉我这个功能的名称是什么是或只是给我一个抽象或明确的代码示例?

据我所知,这个例子就像:你有不同类型的对象,它们都共享同一个界面。使用此接口,可以创建可以存储不同对象类型的列表或数组。

如果有人可以帮助我,我会很高兴...我真的很喜欢我在那里读到的东西,但现在我有一些业余时间,无法找到我从哪里得到这些信息。

提前谢谢!

//编辑:感谢您的快速回答,真实的怀疑!!

4 个答案:

答案 0 :(得分:2)

这与Java 8无关。如果你有不同的对象都实现了相同的接口,让我们称之为MyInterface,那么你可以创建一个这样的数组:

MyInterface[] myArray = new MyInterface[size];

您可以将这些对象分配给此数组的元素。当然,您只能使用MyInterface定义或Object定义中的方法 - 除非您将成员转换回原始类。

列表也是如此。您可以定义一个列表:

List<MyInterface> list = new ArrayList<MyInterface>();

然后您可以将任何实现MyInterface的对象添加到此列表中,当您从该列表中get()时,您可以对成员执行的操作具有相同的限制:只有{{1}的方法1}}和MyInterface,除非你退回。

答案 1 :(得分:0)

我认为您可能正在考虑从5版本开始使用Java的泛型。假设您有一个名为MyInterface的接口和任意数量的实现该接口的类,例如MyClassOne和MyClassTwo。可以创建一个接受任何实现MyInterface的类的集合(例如List),如下所示:

List<MyInterface> theList = new ArrayList<MyInterface>();

然后您可以像这样添加到列表中:

theList.add(new MyClassOne());
theList.add(new MyClassTwo());

以下内容将产生编译错误:

theList.add("A String");

从列表返回的对象将是MyInterfaces。您不会立即知道它是MyClassOne还是MyClassTwo:

MyInterface obj = theList.get(0);
if (obj instanceof MyClassOne) {
    System.out.println("It's MyClassOne");
} else if (obj instanceof MyClassTwo) {
    System.out.println("It's MyClassTwo");
}

这是一个类似于数组的故事 - 任何MyInterface实现类都可以进入,MyInterface实例出来了:

MyInterface[] array = { new MyClassOne(), new MyClassTwo() };
MyInterface obj = array[0];
if (obj instanceof MyClassOne) {
    System.out.println("It's MyClassOne");
} else if (obj instanceof MyClassTwo) {
    System.out.println("It's MyClassTwo");
}

答案 2 :(得分:0)

这是数组的完整示例:

interface Foo {
    String bar();
}

class Impl1 implements Foo {
    String bar() {
        return "This is implementation 1";
    }
}

class Impl2 implements Foo {
    String bar() {
        return "This is implementation 2";
    }
}

public class Main {
    public static void main(String[] args) {
        Foo[] myArray = new Foo[2];
        myArray[0] = new Impl1();
        myArray[1] = new Impl2();
        for (int i = 0; i < myArray.length; i++) {
            System.out.println(myArray[i].bar());
        }
    }
}

输出:

This is implementation 1
This is implementation 2

答案 3 :(得分:0)

您正在考虑的是Java Generics。

public interface MyInterface { public void foo();}
public class Class1 implements MyInterface {public void foo() {System.out.println("1");}}
public class Class2 implements MyInterface {public void foo() {System.out.println("2");}}

public class Main {
   public static void main(String[] args) {
     List<MyInterface> list = new ArrayList<>();

     list.add(new Class1());
     list.add(new Class2());

     list.get(0).foo(); // Prints 1
     list.get(1).foo(); // Prints 2

     Class1 c1 = (Class1) list.get(0); // OK
     c1        = (Class1) list.get(1); // Runtime error - ClassCastException
  }

此外,您可以按如下方式使用通配符:

public static void main(String[] args) {
    List<Class1> list1 = foo1(); // Compiler error - incompatible types
    List<Class1> list2 = (List<Class1>) foo2(); // Warning - unchecked cast

    Class1 class1 = list2.get(0); // OK

    List<Object> list3 = (List<Object>) foo1();

    Class2 class2 = (Class2) list3.get(0); // Runtime error - ClassCastException
}

private static List<? super MyInterface> foo1() {
    List<Object> list = new ArrayList<>();
    list.add(new Class1());
    return list;
}

private static List<? extends MyInterface> foo2() {
    List<? extends MyInterface> list1 = new ArrayList<Class1>();
    list1.add(new Class1()); // Compiler error: the compiler is not aware of the list's runtime type
                             // from the compiler's point of view, list1 could have runtime type List<Class2>

    List<Class1> list = new ArrayList<>();
    list.add(new Class1());
    return list;
}