面向对象三大特征:封装性、继承性、多态性之多态性。
extends继承或者implemens实现,是多态性的前提。
例如:
小菜是一个学生,但同时也是一个人。
小菜是一个对象,这个对象既有学生形态,也有人类形态。
一个对象拥有多种形态,这就是:【对象的多态性】
多态的格式与使用
代码当中体现多态性,其实就是一句话:父类引用指向子类对象。
格式: 分类名称 对象名 = new 子类名称(); 或者: 接口名称 对象名 = new 实现类名称();
访问成员变量的两方式
1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。
Fu obj = new Zi(); System.out.println(obj.num);//Fu
2.间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。
//子类没有覆盖重写,就是父 //子类如果覆盖重写,就是子 obj.showNum();
在多态的代码中,成员方法的访问规则是
看new的谁,就优先用谁,没有则向上找。
口诀:编译看左边,运行看右边。
对比一下:
- 成员变量:编译看左边,运行还是看左边。
- 成员方法:编译看左边,运行看右边。
Fu obj = new Zi();//多态 obj.method();//父子都有,优先用子 obj.methodFu();//子类没有父类有,向上找父类
多态的好处:
无论右边new的时候换成那个子类对象,等号左边调用方法都不会变化。
向上转型和向下转型:
1.对象的向上转型,其实就是多态的写法:
格式: 父类名称 对象名 = new 子类名称(); Animal animal = new Cat(); (创建了一只猫,当作动物看待,没问题)
含义:
- 右侧创建了一个子类对象,把它当作父类来看待使用。
注意事项:
- 向上转型一定是安全的。从小范围转向的大范围,从小范围的猫,向上转换成为了更大范围的动物。
类似于: double num = 100://正确,int——>double,自动类型转换
向上转型一定是安全的,没有问题的,正确的。但是有一个弊端,对象一旦向上转型为父类,那么就无法调用子类原有的内容。
解决方法:用对象的向下转型【还原】
2.对象的向下转型,其实是一个[还原]的动作。
格式: 子类名称 对象名 = (子类名称) 父类对象; Animal animal = new Cat();本来是猫,向上转型为动物 Cat cat = (Cat) animal;//本来是猫,已经被当中动物了,还原回来成为本来的猫
含义:
- 将父类对象,【还原】成为本来的子类对象。
注意事项:
- 必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。
- 如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错。ClassCastException
类似于: int num = (int) 10.0;//可以 int num = (int) 10.6;//不可以
如何才能知道一个父类引用的对象,本来是什么子类?
格式:
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象不能当作后面类型的实例。
Animal animal = new Dog();//本来是一只狗 animal.eat();//狗吃骨头 //如果希望调用子类特有的方法,需要向下转型 //判断一下父类引用的animal本来是不是Dog if(animal instanceof Dog){ Dog dog = (Dog) animal; dog.watchHouse(); } //判断一下animal本来是不是Cat if(animal instanceof Cat ){ Cat cat = (Cat) animal; cat.catchMouse(); }