1. 多态的概述: 是面向对象的三大特性之一, 封装, 继承, 多态.
1一个具体的对象有多种形态, 老虎既属于猫科动物(因为子父类是相对的, 所以猫科动物也可以看做子类), 又属于哺乳动物, 所以老虎既可以拥有猫科动物的属性, 又有哺乳动物的属性.
2Java 中多态的代码体现在一个子类对象 (实现类对象) 既可以给这个子类 (实现类对象) 引用变量赋值, 又可以给这个子类 (实现类对象) 的父类 (接口) 变量赋值.
普通类与普通类, 抽象类与抽象继承类, 接口与接口实现类.
多态中成员变量和成员方法的变化
成员变量 编译和运行都参考等号的左边. 编译运行看左边
成员方法(非静态方法) 编译看左边, 运行看右边.
静态方法 编译看左边, 运行看左边(父类的)
注: 多态创建对象与普通类创建对象对成员变量和成员方法的调用互不影响.
多态中创建的对象, 在调用成员变量时, 必须是父类中具备的, 调用成员方法时, 必须是父类具备的, 但实际调用时是子类的方法.
3.instanceof 关键字, 返回值是布尔类型 true false. 比如: 父类 A, 子类 B, 子类 C,B 和 C 是 A 的子类, 当父类类型 A 变量名 = new 子类类型 B(); 用 instanceof 检测是否属于 A 或 B 时, 返回值是 TRUE, 当检测是否属于 C 时, 返回值是 False. 但检测 A/B/C 以外 的类时, 编译不成功.
多态的转型
父类类型 变量名 = new 子类类型();
如: Person p = new Student();
1多态对象的创建, 就是向上转型的过程. 此时使用的时父类类型的成员变量(隐藏了子类类型), 可以调用各个子类的具体的方法(父类中具有的方法), 但不能使用子类中特有的方法.
向上转型用于, 父类方法的具体实现, 或者使用子类相同方法的不同方法体时.
子类类型 变量名 = (子类类型) 父类类型的变量;
如: Student stu = (Student) p; // 变量 p 实际上指向 Student 对象
此时可以使用子类的方法和子类的属性
2向下转型的前提是向上转型, 所以使用 instanceof 判断具体的对象是否属于父类, 再进行向下转型.
向下转型, 用于使用子类特有的方法., 当提供的对象属于父类对象, 但要使用子类特殊的方法时, 向下转型.
- // 描述动物类, 并抽取共性 eat 方法
- abstract class Animal {
- abstract void eat();
- }
- // 描述狗类, 继承动物类, 重写 eat 方法, 增加 lookHome 方法
- class Dog extends Animal {
- void eat() {
- System.out.println("啃骨头");
- }
- void lookHome() {
- System.out.println("看家");
- }
- }
- // 描述猫类, 继承动物类, 重写 eat 方法, 增加 catchMouse 方法
- class Cat extends Animal {
- void eat() {
- System.out.println("吃鱼");
- }
- void catchMouse() {
- System.out.println("抓老鼠");
- }
- }
- public class Test {
- public static void main(String[] args) {
- Animal a = new Dog(); // 多态形式, 创建一个狗对象
- a.eat(); // 调用对象中的方法, 会执行狗类中的 eat 方法
- // a.lookHome();// 使用 Dog 类特有的方法, 需要向下转型, 不能直接使用
- // 为了使用狗类的 lookHome 方法, 需要向下转型
- // 向下转型过程中, 可能会发生类型转换的错误, 即 ClassCastException 异常
- // 那么, 在转之前需要做健壮性判断
- if( !a instanceof Dog){ // 判断当前对象是否是 Dog 类型
- System.out.println("类型不匹配, 不能转换");
- return; // 返回最开始调用的地方 main
- }
- Dog d = (Dog) a; // 向下转型
- d.lookHome();// 调用狗类的 lookHome 方法
- }
- }
- View Code
来源: http://www.bubuko.com/infodetail-3340294.html