多态
什么是多态?
同类型的对象,表现出的不同形态
多态的表现形式
父类类型 对象名称 = 子类对象;
多态的前提
-
有继承/实现关系
-
有父类引用指向子类对象
Fu f = new zi(); -
有方法重写
多态的好处
使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与遍历
多态中调用成员的特点
-
变量调用:编译看左边,运行也看左边
- javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败
- java运行代码的时候,实际获取的就是左边父类中成员变量的值
-
方法调用:编译看右边,运行看右边
- javac编译代码的时候,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有,编译失败
- java运行代码的时候,实际上运行的是子类中的方法
-
理解:
- Animal a = new Dog();
- 现在是用a去调用变量和方法的
- 而a是Animal类型的,所以默认会从Animal这个类中去找
- 成员变量:在子类的对象中,会把父类的成员变量也继承下
- 成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的
多态的优势和弊端
-
在多态形式下,右边对象可以实现解耦合,便于扩展和维护
-
定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
-
多态不能调用子类的特有功能
- 当调用成员方法的时候,编译看左边,运行看右边,那么在编译的时候会先检查左边的父类中有没有这个方法,如果没有直接报错
- 解决方案:变回子类类型就行(自动类型转换和强制类型转换)
- 细节:转换的时候不能瞎转,如果转成其他类的类型,就会报错
Dog d = (Dog)a;//instanceof 关键字 判断变量是不是这个类型 if (a instanceof Dog) { Dog d = (Dog) a; d.lookHome(); } else if (a instanceof Cat) { Cat c = (Cat) a; c.catchMouse(); } else { sout("没有这个类型,无法转换") }