How to determine the type and return parameters of a Java function using a subclass or superclass?

For example, if I have a function like

public List<E> sort(ArrayList<E> list) {...} 

My classmate told me that we should use List as a return type, because the return type should be as wide as possible. Its reason here is that we can change to return a LinkedList or other type later if we are currently returning an ArrayList. This increases flexibility.

But the parameter of the function that we get should be as narrow as possible. This is due to the fact that we may need to use some function that is implemented only by ArrayList in our sort function.

So my question is this: are there generally accepted guidelines / best practices that recommend that the formal parameters of a function be as narrow as possible? If not, what will be the main arguments against?

===============================================

Just clarify this.

 public List<E> sort(ArrayList<E> list) {...} 

This is just an example, List and ArrayList can be replaced with any other Super Class and Sub. Suppose that some functions exist only in a Sub-class.

 public <E> SuperClass<E> sort(SubClass<E> object) {...} 
+5
source share
3 answers

Most programmers will agree that returning as widely as possible is good (because of the flexibility factor) that you describe.

I believe that many will argue that as a rule, as a rule, this is also the case for parameters, since this allows you to use your function from a wider spectrum: if there is a LinkedList object in some place in the code that this place will be able to call your method (if you need to sort it) if it was defined with a parameter of type List , but it cannot call your method if it was defined with a parameter of type ArrayList .

So overall, as far as possible, this is a good recommendation. Of course, it’s up to you (as the author of the method) to determine what β€œwide” means to you. In particular, if you can make it wider, but with some cost (for example, a more complex implementation), you must decide whether you agree to accept this additional complexity (higher chance of errors) in exchange for wider applicability.

+2
source

To use generics correctly, you must accept and return the same interfaces that are implemented by ArrayList, LinkedList, etc. Remember to return a parameter of type <E> .

 public <E> List<E> sort(List<E> list) { ... return list; } 

This method applies to all List implementations, as shown below (I don’t remember them):

 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); 
+1
source

Your classmate should have told you to start with the right announcement to start with:

 public <<E extends Comparable<? super E>>> List<E> sort(List<E> list) 

because if you want to sort the List without passing a Comparator , these elements must somehow, well, be comparable.

Then, as a rule, returning a List vs ArrayList , the choice should be for List . But not always. Think about Set vs SortedSet for a minute, returning a SortedSet allows you to clear the caller that the returned Set actually sorted; as opposed to returning a Set .

+1
source

Source: https://habr.com/ru/post/1275439/


All Articles