例如,如果我有像
这样的功能public List<E> sort(ArrayList<E> list) {...}
我的同学告诉我,我们应该使用List作为返回类型,因为返回类型应该尽可能广泛。他的理由是,如果我们当前返回一个ArrayList,我们可以更改为返回LinkedList或其他类型。它增加了灵活性。
但我们收到的函数参数应该尽可能窄。这是因为我们可能需要在sort函数中使用一些只由ArrayList实现的函数。
所以我的问题是:是否有任何广泛接受的指南/最佳实践建议函数的形式参数应尽可能窄?如果不是,反对的主要论点是什么?
=============================================
只是澄清一下。
public List<E> sort(ArrayList<E> list) {...}
这只是一个例子,List和ArrayList可以被任何其他Super Class和SubClass替换。我们假设SubClass中只存在一些函数。
public <E> SuperClass<E> sort(SubClass<E> object) {...}
答案 0 :(得分:2)
大多数程序员都会同意,尽可能广泛的回报是你所描述的好事(由于灵活性因素)。
我相信很多人会争辩说,尽可能广泛的指南也适用于参数,因为它允许您从更广泛的范围使用您的函数:如果在代码中的某个位置有LinkedList
如果使用List
类型的参数定义了该方法,那么该地方将能够调用您的方法(如果需要排序),但如果使用参数定义它,则无法调用您的方法类型为ArrayList
。
所以一般来说,尽可能广泛是一个很好的指导方针。当然,由您(作为方法的作者)决定“尽可能广泛”对您来说意味着什么。具体来说,如果你可以使它更广泛但有一些成本(例如,更复杂的实现),你必须决定是否愿意接受这种额外的复杂性(更高的错误机会)以换取更广泛的适用性。
答案 1 :(得分:1)
要正确应用泛型,您应该接受并返回由ArrayList,LinkedList等实现的相同接口。不要忘记返回类型参数<E>
。
public <E> List<E> sort(List<E> list) {
...
return list;
}
此方法适用于以下所有List实现(我不记得所有):
List<String> vector = new Vector<>();
List<String> stack = new Stack<>();
List<String> arrayList = new ArrayList<>();
List<String> linkedList = new LinkedList<>();
List<String> newList1 = new Main().sort(vector);
List<String> newList2 = new Main().sort(stack);
List<String> newList3 = new Main().sort(arrayList);
List<String> newList4 = new Main().sort(linkedList);
答案 2 :(得分:1)
你的同学应该告诉你从正确的声明开始:
List
因为如果你想在不传递Comparator
的情况下对List
进行排序,那么这些元素需要以某种方式,可比较。
然后,一般,返回ArrayList
vs List
,选择应该是Set
。但不总是。考虑SortedSet
vs SortedSet
一分钟,返回Set
使调用者明白返回的Set
实际已排序;而不是返回{{1}}。