多态
背景:代码的复用性不高,而且不利于代码维护
介绍:方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承基础上的
多态的具体体现:
-
方法的多态:重载和重写体现多态
-
对象的多态:
-
一个对象的编译类型和运行类型可以不一致
Animal animal = new Dog(); //animal编译类型是Animal,运行类型是Dog
-
编译类型在定义对象时,就确定了,不能改变
-
运行类型是可以变化的
animal = new Cat(); //animal的运行类型变成了Cat,编译类型仍然是Animal
-
编译类型看定义时 = 号的左边,运行类型看 = 号的右边
//animal 编译类型就是Animal,运行类型是Dog Anima animal = new Dog(); //因为运行时,执行到该行,animal运行类型是Dog,所有cry就是Dog的cry animal.cry(); //animal 编译类型Animal,运行类型是Cat animal = new Cat(); //执行的是Cat的cry animal.cry(); //一个父类的对象引用,可以指向子类的一个对象
-
多态注意事项和细节:
-
多态的前提是:两个对象(类)存在继承关系
-
多态的向上转型
-
本质:父类的引用指向了子类的对象
-
语法:父类类型 引用名 = new 子类类型();
Anima animal = new Cat();
-
编译类型看左边,运行类型看右边。可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;最终运行效果看子类的具体实现,即调用方法时按照从子类(运行类型)开始查找方法,然后调用,规则就是就近
-
-
在编译阶段,能调用哪些成员,是由编译类型决定的
-
在运行阶段,运行哪个方法看运行类型
-
多态的向下转型
- 语法: 子类类型 引用名 = (子类类型) 父类引用
- 只能强转父类的引用,不能强转父类的对象
- 要求父类的引用必须指向的是当前目标类型的对象
- 当向下转型后,可以调用子类类型的所有成员
Animal animal = new Cat(); Cat cat = (Cat) animal; //一开始animal指向Cat对象,不可以调用Cat类的特有方法,此时可以使用向下转型,再使cat指向Cat对象,可以使用Cat类的特有方法 Dog dog = (Dog) animal;//错误 //此时就是让Cat对象变成Dog对象,不可能
-
属性没有重写之说,属性的值看编译类型
-
instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型