1. interface Pet{
    2. }
    3. class PetShop{
    4. private Pet[] pets;
    5. }

    面向对象里面子类的实例都可以赋值给父类的。
    所以 pets[0] = new Cat(); pets[1] = new Dog(); …

    1. 把共性列出来把不同点隐藏这个过程叫**抽象化**。<br />便于关注功能和理顺逻辑,而不要被细节局限,比如今天你只认识两种宠物,明天外国人带来一个你从未见过的宠物你的程序也能工作,那就是一个好的**程序设计**。如果你按你所见过的宠物需要吃什么喝什么来实现程序,那以后就可能新的宠物适应不了。所以在面对具体实现方法之前不要把它们想得太具体,只描述应该达到什么功能,比如:我们需要的是解决宠物的问题,不要管猫和狗吃作息习惯有什么不同,你只要描述吃饭睡觉这些功能,在树上睡还是在地上睡没关系。<br />并且还有将不同的接口直接放入对象数组中,举例:
    1. Pet pet = new Cat();
    2. Pet nextPet;
    3. Pet[] pets = new Pet[]{pet, nextPet};

    假设你有一个名为MyInterface的接口以及任何实现该接口的类,比如MyClassOne和MyClassTwo。它可以创建一个集合(如表),将接受一个实现MyInterface的任何一类,像这样:

    1. ArrayList<MyInterface> list = new ArrayList<>();

    然后,您可以添加到列表中,像这样:

    1. list.add(new MyClassOne());
    2. list.add(new MyClassTwo());

    以下会产生编译错误:

    1. list.add("a string");

    从列表返回的对象将是MyInterfaces。你会不会马上知道,如果它是一个MyClassOne或MyClassTwo:

    1. MyInterface obj = list.get(0);
    2. if (obj instanceof MyClassOne) {
    3. System.out.println("It's MyClassOne");
    4. } else if (obj instanceof MyClassTwo) {
    5. System.out.println("It's MyClassTwo");
    6. }

    这对阵列类似的故事 - 任何MyInterface的,实现类可以进去,并MyInterface的情况下出来:

    1. MyInterface[] array = {new MyClassOne(), new MyClassTwo()};
    2. MyInterface obj2 = array[0];
    3. if (obj2 instanceof MyClassOne) {
    4. System.out.println("It's MyClassOne");
    5. } else if (obj2 instanceof MyClassTwo) {
    6. System.out.println("It's MyClassTwo");
    7. }
    1. It's MyClassOne
    2. It's MyClassOne

    参考链接:
    http://cn.voidcc.com/question/p-mfyyfmrk-kw.html
    https://zhidao.baidu.com/question/751488965117303484.html