本章内容
- 多态的定义
- 多态的前提
- 多态的格式
- 多态的好处
- 访问类中成员变量的两种方式
- 转型—向上转型、向下转型
- 转型异常
多态
概述:多态是继封装继承之后面向对象的第三大特征
定义: 多态指的是同一行为,具有多种不同表现形式,生活中,比如跑的动作,猫狗大象跑起来的形态是不一样的,比如飞的动作,昆虫鸟飞机的飞行动作是不一样的。可见同一行为,通过不同的事物,可以表现出不同的形态,这就是多态。
前提条件
- 继承或者实现(二选其一)
- 父类引用指向子类对象
- 必须有方法的重写(不重写没有意义)
多态的表现格式
父类类型 变量名 = new 子类对象;
变量名.方法名();
父类类型:指的是子类对象继承父类类型,或者是实现父接口类型。
public class Fu{
public void method(){
System.out.println("这是父类的方法");
}
}
//1.继承
public class Zi extends Fu{
//2.重写
@Override
public void method(){
System.out.println("这是子类的方法");
}
}
public class TestPoly{
public static void main(String []args){
//3.父类引用指向子类对象
Fu fu=new Zi();
fu.method();//本质调用的是子类重写之后的method方法
}
}
如果在使用多态调用方法时,首先检查父类当中是否有该方法,如果没有,则编译报错,如果有,实际执行的是子类重写之后的方法
多态的好处
在实际开发中,父类类型一般作为方法的形式参数,传递子类对象(实际参数)给方法,进行方法的调用,更能体现出多态的扩展性和便利性。
public abstract class Animal{
public abstract void rat();
}
public class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗啃骨头");
}
}
public class Test{
public static void main(String []args){
Cat c=new Cat();
showCatEat(c);
Dog dog=new Dog();
showDogEat(d);
Cat c2=new Cat();
showAnimalEat(c2);//猫吃鱼
}
/* public static void showCatEat(Cat cat){
cat.eat();
}
public static void showCatEat(Dog dog){
dog.eat();
}
*/
/*
以上两个方法均可以用多态进行优化
*/
public static void showAnimalEat(Animal animal){
animal.eat();
}
}
说明: 由于多态特性的支持,showAnimalEat方法中的Animal类型,是Cat和Dog的父类类型,父类类型接收子类对象,当然可以吧cat对象和dog对象传递给参数。
在执行过程中,执行eat方法实际执行的是各自子类对象重写之后的eat方法。
不仅仅可以做到代替,在扩展性方面,无论之后出现多少个子类,都不需要编写showXxxEat方法了,直接使用showAnimalEat方法。
访问类中的成员变量的两种方式
- 直接通过对象名访问成员变量:看等号左边是谁就优先调用谁,如果没有就向上找。
- 间接通过成员方法访问成员变量:看该方法属于谁就优先调用谁,没有就向上找。
引用数据类型的转型
多态的转型分为向上转型和向下转型
向上转型: 多态本身就是子类类型象父类类型向上转型的过程,这个过程是默认的,当一个父类引用指向子类对象,就是向上转型
使用格式
父类类型 变量名 =new 子类类型();
比如: Animal animal =new Cat();
向下转型: 父类类型向子类类型向下转换的过程,这个过程是强制的。
一个已经向上转型的子类对象,将父类的引用转为子类引用,可以使用强制类型转换
使用格式
子类类型 变量名=(子类类型) 父类变量名;
比如: Cat cat=(Cat) animal;
转型异常
在向下转型过程中,一不小心就会出现 java.lang.ClassCastException 类转换异常,为了避免类型转换异常,java提供了instanceof 关键字,为引用变量做类型的校验。
格式
变量名 instanceof 数据类型
如果变量属于该数据类型,则返回true
如果变量不属于该数据类型,则返回false
所以在转换前,最好先进行引用变量的类型判断。
public class Test{
public static void main(String []args){
//向上转型
Animal animal =new Cat();
//向下转型
if(animal instanceof Cat){
//表明你就是一只猫
Cat cat=(Cat) animal;
cat.eat();
cat.catchMouse();
}else if( animal instanceof Dog)
// 表明你就是一只狗
Dog dog=(Dog) animal;
dog.lookDoor();
}
}