### 继承
继承是复用代码的一种非常重要的方式,在声明类时显示的使用extends关键字继承另一个类,即可获得这个类中的全部域,包括成员变量和方法。
一个类在虚拟机中的存在方式:虚拟机加载类后,在方法区生成这个类的java.lang.Class对象,在常量池中保存这个类的常量和成员变量,生成一个方法表用来记录类中所有方法的引用,方法的代码也存放在方法区中。
### 多态
多态在Java中实际上指的是方法的多态,最常见的是父类引用指向子类对象时通过引用调用方法,这时会根据不同的情况调用父类或子类中的方法。
父类引用指向子类对象时,可以直接通过引用调用父类中的所有方法以及子类中重写父类的那些方法,不能调用子类独有的方法。
`多态的原理`:在方法区中存在方法表,方法表中存放着该类的所有方法的引用,一般有三个部分,从object类继承得到的方法,位于方法表的最上方,引用指向Object类的方法代码,如果该类重写了Object类的方法,则该方法的引用指向子类自己的方法代码。第二部分是继承自父类的方法,一般指向父类的方法代码,如果重写了则指向自己的方法代码。第三部分是自己实现的方法,指向自己的方法代码。
![](https://leanote.com/api/file/getImage?fileId=5b7299b9ab64410455001e50)
由此可以看出,父类中的每一个方法在方法表的行数在子类的方法表中是一致的,因此可以通过偏移量来确定方法的位置。所以通过父类引用调用方法时,先在父类的方法表中找到方法的位置偏移量,再根据这个偏移量在子类的方法表中找到对应的方法进行调用。
如果子类重写了方法,那么调用子类自己的方法代码,如果子类没有重写,则沿着继承层次从上往下到达第一个拥有此方法的方法代码的类,调用这个类的该方法代码。随着继承的层次越多,这个查找的过程会消耗更多的时间,方法表也会越来越长。
同时,也可以看出,父类引用指向子类对象,在父类的方法表中是找不到子类自己实现的方法的,所以不能通过这个父类引用调用子类独有的方法。
[参考文章](https://www.ibm.com/developerworks/cn/java/j-lo-polymorph/)https://www.ibm.com/developerworks/cn/java/j-lo-polymorph/