这已经困扰了我一段时间,还没有找到一个可以接受的答案。假设一个类是一个子类或实现一个接口,为什么我会使用Parent类或Interface作为Type。
List list = new ArrayList();
Vehicle car = new car();
就ArrayList而言,现在只允许我访问List方法。如果我有一个将List作为参数的方法,那么我可以将List或ArrayList作为ArrayList IS A List传递给它。显然在方法中我只能使用List方法,但我看不出将其类型声明为List的理由。据我所知,它只限制了我允许在代码中使用的方法。
List list = new ArrayList()的场景比ArrayList list = new ArrayList()更受欢迎。
答案 0 :(得分:2)
您编写的程序可以围绕多个类和方法传递列表。您现在想要在多线程环境中使用它。如果你是明智的并且将所有内容都声明为List
,那么现在可以对一行代码进行一次更改:
List list = Colllections.synchronizedList(new ArrayList());
如果您已将列表声明为ArrayList
,则必须重新编写整个程序。故事的寓意 - 始终编程到代码所需的限制性最小的界面。
答案 1 :(得分:1)
如果您只需要父类型的功能,通常建议使用接口或父类型。我们的想法是明确记录您并不真正关心实现,从而使以后更容易更换具体类。
一个很好的例子是Java集合类:
如果您始终使用List
,Set
等,而不是例如ArrayList
,您可以稍后从ArrayList
切换到LinkedList
,如果您发现它提供了例如List
更好的性能。要做到这一点,只需更改构造函数(您甚至不必更改所有构造函数,您可以混合使用)。其余代码仍然看到ArrayList
的实例并继续工作。
如果您明确地使用了ArrayList
,则必须在使用它的任何地方更改它。如果你实际上并不需要{{1}},那么在界面上使用它就无法获得任何好处。
这就是为什么通常建议(例如在“Effective Java”(J.Bloch),第52项:“通过接口引用对象”。)尽可能仅使用接口。
另请参阅此相关问题:Why classes tend to be defined as interface nowadays?
答案 2 :(得分:1)
关键是接口或基类限制您可以对变量执行的操作。例如,如果稍后重构代码以使用该接口或基类的另一个实现,则不必担心 - 您不依赖于实际类型的标识。
另一件事是它经常使得阅读代码更容易,例如如果您的方法的返回类型为List
,您可能会发现返回类型为List
的变量更具可读性。
答案 3 :(得分:1)
接口指定了一个契约(这件事做了什么),一个实现类指定了实现细节(它是如何做的)。
根据良好的OOP实践,您的应用程序代码不应与其他类的实现细节相关联。使用界面可以使应用程序松散耦合(阅读:Coupling)
此外,使用接口可让客户端代码在不同的实现中传递,并使用Collections.synchronizedList()
,Collections.unmodifiableList()
等方法应用装饰器模式。
答案 4 :(得分:1)
List list = new的场景 ArrayList()优于ArrayList list = new ArrayList()会很多 赞赏。
一个具体的例子:如果它是一个字段声明而你有一个setList()
,当然应该使List
参数变得灵活。
对于局部变量(以及没有setter的字段),使用接口类型几乎没有什么好处。根据一般原则,很多人都会这样做。
答案 5 :(得分:0)
你是对的。在这些情况下,变量是字段或局部变量,它们是不公共接口,它们是实现细节。应详细说明实施细节。你应该将ArrayList称为ArrayList,因为你只是故意选择它来实现它。
回收陈词滥调的人:看看你的帖子并多思考一下。这是无稽之谈。
我之前的回答是低估了死亡: