我知道在Java中,大多数人使用以下方式声明一个列表:
List l = new ArrayList();
但是那和
之间会有什么区别AbstractList l = new ArrayList();
在此特定实例中,在抽象类上使用接口有什么好处?
答案 0 :(得分:3)
层次结构就像......
ArrayList extends AbstractList implements List
和
AbstractList implements List
所以,
无论何时创建ArrayList
的对象,如下所示,您将参考ArrayList
List
的对象
List list = new ArrayList();
需要注意的另一件事是,为什么需要在两个类中实现List
,
所以,
它是为了显示ArrayList实现List。 整张图中的AbstractList只是为了方便起见 减少List实现之间的代码重复。
答案 1 :(得分:3)
在这种情况下,它不会真正不同。但是,将接口用作变量类型是一种常见的代码样式,因为AbstractWhatever
类的抽象实现意味着可以更轻松地创建实现而无需在接口中实现所有方法。
所以这是一个风格问题,而不是技术问题。
答案 2 :(得分:1)
原始答案:
抽象类允许您定义一些共享功能,同时保留其他功能由实现定义。因此,如果要创建一组具有共享某些功能但具有自定义功能的类似类,则抽象类很有用。
界面不允许您定义任何功能。它只是定义了一组方法签名,您知道可以在实现该接口的类的任何对象上调用它们。
我会说接受的做法不是使用抽象类来填充接口的角色。也就是说,抽象类应该用于您定义的相关类之间的代码共享,而接口应该用于抽象。
不使用抽象类来填充接口角色的一个原因是类不能从多个类继承,但它可以实现许多接口。因此,使用抽象类比使用接口更多地限制了您的设计。
编辑:
在这个特定的实例中,不同之处在于,如果您稍后重新分配l
以包含实现List
但不派生自AbstractList
的对象,则您的代码将抛出异常。并非所有实现List
的类都会扩展AbstractList
。
使用AbstractList
限制您仅使用从核心AbstractList
功能派生的列表。另一方面,任何人都可以编写一个使用全新代码实现List
的类,如果你使用List
类型的变量,那么你仍然可以与他们的新类兼容从未见过。
Java的列表派生自AbstractList
这一事实应被视为Java库内部的实现细节,而不是您应编写的接口。