多态
什么是多态:
多态是同一父类类型,调用同一个方法后,表现出不同的状态。(比如宠物这个类,有吃的方法,它们的子类也都有吃的方法,在调用父类吃的方法过程中,根据不同的动物有不同的吃的行为)
好处:当程序业务有扩展是,使用多态代码改动量最小
概念:同一类型,调用统一方法,表现出不同状态。
实现方式:
方法重载:静态方式实现多态
方法重写:动态方式实现多态
多态的使用步骤:
- 1,虚方法(在父类中编写共同的方法):
public void eat(){
//方法体为空
} - 2,在子类中重写父类中的虚方法
重写:子类的方法头和父类中被重写方法的方法头相同(也称为方法的覆盖) - 3,使用时,用父类的成员做参数,但是传递过程中用子类的对象(例如宠物都有主人,主人的喂食方法中,参数是父类类型)
里式替换原则LSP:任何父类出现的位置,都可以使用其子类对象进行替换,方法的参数是父类类型,传递实参时,传递其子类对象
多态的特点:
父类:方法(虚方法)
子类:重写父类中的虚方法
多态的实现方式和区别:
- 1,方法重载:是一种静态的方式实现多态,在程序编译的过程中,重载的方法就已经确定,重载的若干个方法同时都加载到内存中。根据传进来的参数类型和个数的不同来判断调用哪一个重载方法。
- 2,方法重写(覆盖):在编译时(加载内存时),子类的方法并没有覆盖掉父类中被重写的方法,只有在调用的过程中,判断是哪个子类调用的,然后用这个子类中的方法去覆盖父类中的方法。
由于参数的类型是父类类型,所以调用的是父类空间中的方法,根据具体传递的实参(实参是哪个子类类型),就使用这个子类中的方法去覆盖掉父类中的虚方法。
多态的应用之一:对象数组
复习一下数组特点:
1,数据类型相同
2,内存空间连续
3,长度固定
例如:声明一个数组,存放各个宠物对象,数组类型是父类Pet,根据LSP,数据类型时Pet,数组中的元素可以使Pet的子类。
父类的类型指向子类的引用。
Pet p = new Cat();
p = new Dog();
通过父类声明的变量,只能访问Pet类中的成员,而不能访问父类的子类中的独有成员,此时可以通过setter和重写来访问
(声明在方法内部或者方法语句块内部的变量叫做局部变量,局部变量不能重名,但局部变量和属性可以重名)
多态的应用之二:设计模式
模式可以理解为做一件事比较好的那个方法
设计模式:开发过程中完成一个功能的比较好的实现方式(Java里有23种设计模式)
创建对象的方式:声明一个工厂来生产对象,在需要对象的时候,找工厂生产即可。
解决集中创建对象的问题就是简单工厂设计模式- 1,首先在各个类中添加构造方法
- 2,创建一个工厂类(如PetFactory)
- 3,在工厂类中编写创建对象的方法:
- 3.1)方法的返回值必须是父类类型
- 3.2)方法的参数必须包括所有的子类需要的所有参数。再在所有参数后面额外加一个type参数,用来和创建哪个子类对象进行匹配。
- 3.3)判断类型,创建对象。例如用switch来进行判断,用type座switch的参数,逐一对比。
好处:创建对象无需自己new,二是调用工厂方法即可。当子类没有确定,类名和参数频繁变化的时候,只需要修改工厂类一处即可,整体改动最少。