![dab7902d4e9d6a93e789aff2d3c9cf14.png](https://i-blog.csdnimg.cn/blog_migrate/a7ca6a81d19ae0fe3a070d503334d229.png)
面向对象编程(Object Oriented Programming)有三大特性:封装、继承、多态。在这里,和大家一起加深对三者的理解。
封装
封装可以拆开理解,装,是把数据和方法放进了类里;封,把装进去的数据和成员方法加上访问权限。对于外界,内部细节是透明的,暴露给外面的是它的访问方法。
继承
继承,是为了重用父类代码。两个类若具有is a的关系就可以用extends。另外,继承也为实现多态做了铺垫。
多态
程序中定义的引用变量(java有两大数据类型,内部数据类型和引用数据类型)所指向的具体类型和通过该引用变量发出的方法调用在编译时并不确定,而是在程序运行期间才确定,即一个引用变量到低指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。
在理解多态时,总是逃不掉“向上转型”。
问题的核心在于,一般情况下,在子类继承父类后,子类具有父类的所有成员和方法。但是在向上转型之后,子类中一些独有的成员和方法对于该父类类型的引用变量则“不可见”。
实例
![1fa903f3a09cb125808467175601a2ac.png](https://i-blog.csdnimg.cn/blog_migrate/2e36f5e56471e78479c68d81a3cf25cc.jpeg)
![3391fccfac232b9e55f6ec28db999882.png](https://i-blog.csdnimg.cn/blog_migrate/abd9ae723b63ac57b9543c832a447c02.jpeg)
结果:
![53cd708dec0b99f890bbeafcbc8a4bbe.png](https://i-blog.csdnimg.cn/blog_migrate/fbb7199202d52f9fd2ef2aa610eca2ff.png)
Animal animal = new Lion(); 向上转型后的Animal类型的引用,丢失了重载的方法run(),即子类中的run(),指向的是父类的run(),因此输出“Animal在奔跑”,而不是“Lion在奔跑”。run()方法中调用了sing()方法,因为sing()方法被重写,引用能够找到sing()方法,因此引用调用此sing()方法(动然调用),输出“Lion在唱歌”。
实现多态的必要条件为:继承、重写、向上转型(或者说父类引用指向子类对象)。其实现机制为:调用那个方法是由被引用对象的类型决定,而不是引用变量的类型决定的,并且这个被调用的方法必须是被子类重写过的。
总结:
使用父类的引用指向子类对象
该引用只能调用父类中定义的方法和变量
若子类重写了父类的一个方法(只能重写方法,不能重写变量,否则编译时期会报错),那么调用的时候会调用子类的这个方法。
此外,在多态引用时,可能会涉及到超类的构造方法。调用超类的构造方法的顺序是先调用最远的超类的构造方法。