有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java变量类型和实例化

这已经困扰了我一段时间,还没有找到一个可以接受的答案。假设一个类是一个子类或实现一个接口,为什么我要使用父类或接口作为类型,即

List list = new ArrayList();
Vehicle car = new car();

就ArrayList而言,现在只允许我访问List方法。如果我有一个将列表作为参数的方法,那么我可以将列表或ArrayList传递给它,因为ArrayList是一个列表。显然,在这个方法中,我只能使用List方法,但我看不到将其类型声明为List的理由。就我所见,它只是将我限制在代码中其他地方允许使用的方法上

如果List List=new ArrayList()比ArrayList List=new ArrayList()更好,我们将不胜感激


共 (6) 个答案

  1. # 1 楼答案

    关键是接口或基类限制对变量的操作。例如,如果您稍后重构代码以使用该接口或基类的另一个实现,那么您就没有什么可担心的了——您不依赖于实际类型的标识

    另一件事是,它通常使读取代码更容易,例如,如果您的方法的返回类型是List,您可能会发现返回类型为List的变量更具可读性

  2. # 2 楼答案

    如果您只需要父类型的功能,通常建议使用接口或父类型。这样做的目的是明确地说明您并不真正关心实现,从而使以后更容易将具体类替换为不同的类

    Java集合类就是一个很好的例子:

    如果您总是使用ListSet等来代替例如ArrayList,那么您可以稍后从ArrayList切换到LinkedList,如果您发现它提供了例如更好的性能。要做到这一点,只需更改构造函数(您甚至不必全部更改它们,您可以混合使用)。代码的其余部分仍然可以看到List的实例并继续工作

    如果您确实显式地使用了ArrayList,则必须在使用它的任何地方都对其进行更改。如果您实际上并不特别需要ArrayList,那么在接口上使用它并没有什么好处

    这就是为什么一般建议使用它(例如,在“有效Java”(J.Bloch)中,第52项:“通过对象的接口引用对象”。)尽可能只使用接口

    另见这一相关问题:Why classes tend to be defined as interface nowadays?

  3. # 3 楼答案

    接口指定契约(这件事做什么),实现类指定实现细节(它是如何做的)

    根据良好的OOP实践,应用程序代码不应与其他类的实现细节相关联。使用接口使应用程序保持松散耦合(读取:Coupling

    此外,使用接口可以让客户机代码在不同的实现中传递,并使用Collections.synchronizedList()Collections.unmodifiableList()等方法应用装饰器模式

  4. # 4 楼答案

    您可以编写一个程序,在几个类和方法之间传递列表。现在,您希望在多线程环境中使用它。如果您明智地将所有内容声明为List,那么现在可以对一行代码进行一次更改:

    List list = Colllections.synchronizedList(new ArrayList());
    

    如果将列表声明为ArrayList,则必须重新编写整个程序。故事的寓意是——始终将编程设置为代码所需的限制最少的接口

  5. # 5 楼答案

    A scenario where List list = new ArrayList() is better than ArrayList list = new ArrayList() would be much appreciated.

    一个具体的例子:如果它是一个字段声明,并且您有一个setList(),那么当然应该使用一个List参数来灵活处理

    对于局部变量(以及没有设置器的字段),使用接口类型的具体好处很少。不管怎样,很多人都会按照一般原则去做

  6. # 6 楼答案

    你是对的。在这些情况下,变量是字段或局部变量,它们是而不是公共接口,它们是实现细节。应详细说明实施细节。您应该将ArrayList称为ArrayList,因为您只是特意为实现选择了它

    回收陈词滥调的人:看看你的帖子,多想想。这是胡说八道

    我先前的答案被否决了:

    Use interface or type for variable definition in java?