When to use Supertype or Subtype when returning the method?

Asked

Viewed 311 times

7

Suppose I have a method called "meuMetodo()" that returns an Object of Type ArrayList<String>, i can make this method declare that returns more concrete or more abstract types:

  • public ArrayList<String> meuMetodo() {...}
  • public List<String> meuMetodo() {...}
  • public Collection<String> meuMetodo() {...}
  • public Object meuMetodo() {...}
  • Is there any "good practice" convention on which type to declare as return for each context?
  • What are the advantages, disadvantages and limitations of declaring a more abstract type as return? (like List, Collection, or even Object)
  • What are the advantages, disadvantages and limitations of declaring a more concrete type as return? (in this example, the most concrete would be the Arraylist)

I wish for a canonical response that takes into account things like:

  • It makes a difference if the method in question will be overwritten by a subclass in the future (I lose flexibility to the extend depending on what I declare as Return Type)?
  • It is important to consider what the Clients of this method (the codes that will call it) need from the returned Object (for example, the methods they will call in the returned Object)?
  • It is important to consider for which methods the returned object will be sent as argument?

1 answer

4


  • It makes a difference if the method in question will be overwritten by a Subclass in the future (I lose flexibility when extending depending on
    than I declare as Type of Return)?

Yes. It makes a difference. Imagine you have the supertype:

public interface MySupertype{
  List<String> myMethod()
}

in its subtypes you can return different implementations of List that your code will work:

class ArraySubType implements MySupertype{
  public List<String> myMethod(){
    return new ArrayList<String>();
  }
}

class LinkedListSubType implements MySupertype{
  public List<String> myMethod(){
    return new LinkedList<String>();
  }
}

otherwise, if you declare a concrete type in the supertype, you lose flexibility as you are forcing the subtypes to use a specific implementation of your return type.

  • It is important to consider what the Clients of this method (the codes that will call it) need from the returned Object (for example, the methods they will call in the returned Object)?

  • It is important to consider for which methods the returned object will be sent as argument?

As a general rule, yes. If customers of your type/method need to make many Caps or get encapsulated the returned object in Dapters, this is an indication that the type was poorly designed. On the other hand, it should be taken into account that a guy with many methods, who serves many customers may be violating the ISP (principle of segregation of interfaces).

In short: when declaring a method in a type, mainly interfaces and abstract classes, for both parameters and return objects, you should use the type that is as abstract as possible, but has the necessary methods to manipulate the object or does not force you to cast. This is called "programming for the interface, not for the implementation".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.