最近刷了一些算法题,发现有些题目出现了这样的代码

Queue<Integer> queue = new LinkedList<>();
//为什么不是如下的代码
Queue<Integer> queue = new Queue<>();
LinkedList<Integer> queue = new LinkedList<>();

由于底子不好,当时很好奇为什么左边队列,右边链表,后来复习java基础时,看到了这是一个多态的简单示例。因此重新去学习了一下多态。
首先new出来的是一个链表,链表本身是实现了队列,注意Queue是API中是一个接口,所以Queue不能new对象,只能由实现类的对象来用。
那么问题来了,为什么不直接两边都用LinkedList呢,还有一个问题:

//由于接口不能new对象,那如果是两个类,一个继承另一个呢。为什么不使用父类或者子类对象呢
Person a = new Student();
Student a = new Student();
Person a = new Person();

 首先要明确我们的用意,既然写出了多态的代码,就意味着我们应该用的是子类的方法。那么只创建父类对象并不能满足我们的需求。

Student a = new Student();
Queue<Integer> queue = new Queue<>();

 其次,在原理上分析,多态是继承了类或者实现了接口,继承时重写了部分方法的。而当你使用多态时,你用的是Person对象,但是你调用某个方法时,是子类重写的方法。而且你的person对象不允许调用子类的特殊方法。子类在继承类或许实现接口时,一般都会扩展一些额外的方法,这些就是特殊方法。到这里,我的疑问是,这里用子类也可以,为什么不用子类呢?
 实际上,我在牛客网的编程题中,改成了LinkedList<integer> queue = new LinkedList<>();也编译通过,所以这个是可行的,那么问题来了,这里为什么大家都偏向于使用多态,而不是子类对象的直接调用,并且多态还不允许调用特殊方法。多态的现象很容易理解,但是为什么使用多态,什么时候使用多态才是个问题。
 理解1:如果是继承的父类。首先回去理解一下继承。父类中的private标识的属性和方法,只允许本类使用,子类就算是继承也只有拥有属性,但是用不了。那我又想使用这些私有的属性和方法,还想用子类的重写后的特殊方法,此时就使得多态的出现有意义了。
 理解2:如果是类实现的接口。由于接口可以被多个类实现,用来降低耦合性,并将公共部分抽取到接口中,但是接口中没有什么私有的属性和方法,所以和理解方式1有所不同,采用逆推的思路,我想有一个队列,那就给你一个队列,但是队列接口没有实现,好,那就给你一个队列实现的类(链表),但是,你可别想多了,你只想要队列,那我链表类实现了队列的方法给你用,但是其他的方法不能暴露给你。(既然你只要队列,那就只暴露实现类对应的方法,实现类中的其他方法不给你,这样你拿到的就是一个完全实现了Queue接口的链表,而没有多余的功能,虽然是new的是链表,但是此时的链表只有Queue所有的特性,且失去了链表的其他特性)。
 理解2也适用于理解1的情况。另外有这样的说法,多态是一种类型的多种形态,因此自己综合理解下来就是,你不是继承和实现了吗,那你们肯定有公共的部分,这些公共的部分有些通过重写或者实现的方式,发生了变化,比如接口方法为空,实现后有具体的方法,父类某方法输出1,继承子类重写后输出2,对于这部分产生了多种形态(对于同一个方法名,到底调用这个方法是1还是2)。这样不确定的形态,就是多态。
PS:不知道自己理解的对不对,反正最后说服了自己。如果以后有机会看到设计模式,或者深入学习,可能会对多态有更深刻认识。</integer>