通常我们使用代码进行接口:
List<String> list = new ArrayList<String>();
我们可以写以下内容吗?
AbstractList<String> list = new ArrayList<String>();
这种特定初始化的缺点是什么?任何见解将不胜感激。
答案 0 :(得分:4)
将列表定义为AbstractList
会将您的实施与AbstractList
的子类联系起来,而使用List
界面可以分配给list
变量该接口的任意实现。
将列表定义为AbstractList
还可以访问AbstractList
不属于List
接口的{{1}}方法,但不需要进行转换,但是使用它们会使你的代码不那么灵活。
如果你没有充分的理由去做,那就不要这样做。
答案 1 :(得分:1)
主要的缺点是一般的:在Java中,你一次只能从一个类继承,而你可以实现任意数量的接口。
如果list是私有或本地变量,那么初始化接口几乎没有优势。
你会更好ArrayList<String> list = new ArrayList<String>();
但是,如果您有公共字段或方法参数,那么使用最不具体的声明(接口)会更好。抽象类也实现了接口,因此可以使用它。但是,类的使用者可以使用任何实现接口的类,而这个类可以继承他们可能喜欢的任何其他类。
答案 2 :(得分:1)
使用List<String>
而不是AbstractList<String>
的优势在于List
指定了合同,而AbstractList
指定了(部分)实现。使用List
可确保您的代码与List
的任何实现兼容,而不仅仅是从AbstractList
派生的代码。
虽然遵循这种做法可能看起来并不像是变量声明那么大,但是在完成代码后使用这种做法可以确保整个应用程序具有更大的灵活性。
答案 3 :(得分:0)
使用AbstractList
这样的一个缺点是你限制自己使用扩展AbstractList
的列表类。在没有List
作为超类的情况下实现AbstractList
接口是完全可能的。
第二个缺点是这不会编译:
List<String> list = new ArrayList<String>();
AbstractList<String> list2 = list;
Java类型系统不会让您假设每个List<String>
都是AbstractList<String>
。