开发者

I'm confused about Polymorphism

I'm know polymorphism rule that we can send it via parameter like this code

interface Animal {
  void whoAmI();
}

class A implements Animal{

    @Override
    public void whoAmI() {
        // TODO Auto-generated method stub
        System.out.println("A");
    }

}

class B implements Animal{

    @Override
    public void whoAmI() {
        // TODO Auto-generated method stub
        System.out.println("B");
    }

}

class RuntimePolymorphismDemo {

开发者_Python百科public void WhoRU(List t){
    System.out.println(t.getClass());
}

public static void main(String[] args) {
     A a = new A();
     B b = new B();

     RuntimePolymorphismDemo rp = new RuntimePolymorphismDemo();
     rp.WhoRU(a);
     rp.WhoRU(b);
  }
}

but

 List<Example> examples = new ArrayList<Example>();

In the above code, I don't understand why we must use List<Example>.

Why we can't use like this?

ArrayList<Example> examples = new ArrayList<Example>();

Because when we use List<Example> we can't use method that only exists in ArrayList class like trimToSize()

How I can know when to use or not use?


The reason for using List and not ArrayList, is when you want to use the feature of a List and do not care about its implementation, then just using the base interface or abstract class gives you more flexibility.

If you need to special features of an ArrayList, then you can specify it, but if in the future you decide to change implementation to something other than ArrayList, it makes it difficult to change (as you have to change your code everywhere it is referenced, rather than just the underlying code).


List is an interface. ArrayList is a concrete type, an implementation.

If you only needto use features from List then you would declare your variable to be a List. Then, should a useful new implementation of List become available (MySuperFastList, say) you can swap it over in the code and only need to make one change.


is the same as, by extending your example code, we say:

Animal a=new A();
Animal b=new B();

You can assign a "more derived type" to a less derived one without any problem, actually you can construct, always reffering your example, an array of Anymal, fill it with some A instance and B istances and see polymorfism at work by looping on the array and call on each "Animal" WhoAmI()


This code,I'm don't understand why we must use List. why we can't use like this?

ArrayList<Example> examples = new ArrayList<Example>();

First off, please don't feel like you can't do this - this is perfectly legal.

Since that's legal, then its perfectly natural to question why you often see code like this:

List<Example> examples = new ArrayList<Example>();

Because when we use List we can't use method that only have in ArrayList class like trimToSize()

Again, you got a very good grasp of polymorphism. This is indeed a ramification of using List here instead of ArrayList.

List<Example> examples = new ArrayList<Example>();

Using the interface List here instead of the concrete class ArrayList follows a common best practice: to use interfaces instead of concrete classes whenever possible, e.g. in variable declarations, parameters types, and method return types. The reason this is considered a best practice is:

  1. Using the interface for declarations and for return types hides an implementation detail, making it easier to modify in the future. For example, we may find that the code works better using a LinkedList rather than ArrayList. We can easily make this change in one place now, just where the list is instantiated. This practice is especially key for method parameter types and method return types, so that external users of the class won't see this implementation detail of your class and are free to change it without affecting their code.

  2. By using the interface, it may be clearer to a future maintainer that this class needs some kind of List, but it does not specifically need an ArrayList. If this class relied on some ArrayList-specific property, i.e. it needs to use an ArrayList method, than using ArrayList<Example> examples = ... instead of List<Example> examples = ... may be a hint that this code relies on something specific to an ArrayList.

  3. It may simplify testing/mocking to use the more abstract List than to use the concrete class ArrayList.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜