Why do we first declare subtypes as their supertype before we instantiate them?

前端 未结 12 933
轻奢々
轻奢々 2021-02-01 19:27

Reading other people\'s code, I\'ve seen a lot of:

List ints = new ArrayList();
Map map = new HashMap();
相关标签:
12条回答
  • 2021-02-01 19:38

    @Bhushan answered why. To answer your confusion Why nobody uses

    CharSequence s = new String("String");
    

    or

    OutputStream out = new PrintStream(OutputStream);
    

    CharSequence contains only few common methods. Other classes that implement this interface are mostly buffers and only String is immutable. CharSequence defines common api for classes backed by char array and This interface does not refine the general contracts of the equals and hashCode methods (see javadoc).

    OutputStream is low-level api for writing data. Because PrintStream adds extra convenient methods for writing - higher level of abstraction, it's used over OutputStream.

    0 讨论(0)
  • 2021-02-01 19:39

    This (good) style of declaring the type as the Interface the class implements is important because it forces us to use methods only defined in the Interface.

    As a result, when we need to change our class implementations (i.e. we find our ArraySet is better than the standard HashSet) we are guaranteed that if we change the class our code will work because both classes implement the strictly-enforced Interface.

    0 讨论(0)
  • 2021-02-01 19:40

    For

    List<E> ints = new ArrayList<E>();
    Map<K, V> map = new HashMap<K, V>();
    

    List and Map are the interfaces, so any class implementing those interfaces can be assigned to these references.

    ArrayList is one of the several classes (another is LinkedList) which implement List interface.

    Same with Map. HashMap, LinkedHashMap, TreeMap all implement Map.

    It is a general principle To program for interfaces and not for implementations. Due to this, the programming task becomes easier. You can dynamically change the behavior of the references.

    If you write

    ArrayList<E> ints = new ArrayList<E>();
    HashMap<K, V> map = new HashMap<K, V>();
    

    ints and map will be ArrayList and HashMap only, forever.

    0 讨论(0)
  • 2021-02-01 19:44

    When you at some point decide to use a different implementation, say:

    List<E> ints = new LinkedList<E>();
    

    instead of

    List<E> ints = new ArrayList<E>();
    

    this change needs to be done only at a single place.

    There is the right balance to strike:

    usually you use the type which gives you the most appropriate guarantees. Obviously, a List is also a Collection which is also something Iterable. But a collection does not give you an order, and an iterable does not have an "add" method.

    Using ArrayList for the variable type is also reasonable, when you want to be a bit more explicit about the need for fast random access by object position - in a LinkedList, a "get(100)" is a lot slower. (It would be nice if Java had an interface for this, but I don't think there is one. By using ArrayList, you disallow casting an array as list.)

    0 讨论(0)
  • 2021-02-01 19:45

    This is programming to the interface not the implementation, as per the Gang of Four. This will help to stop the code becoming dependent on methods that are added to particular implementations only, and make it easier to change to use a different implementation if that becomes necessary for whatever reason, e.g. performance.

    0 讨论(0)
  • 2021-02-01 19:51

    Using interfaces has the main advantage that you can later change the implementation (the class) without the need to change more than the single line where you create the instance and do the assignment.

    0 讨论(0)
提交回复
热议问题