关于多态中的几个概念:
* 向上转型(upcasting)
* 子类型–>父类型
* 又被称为自动类型转换
* 向下转型(downcasting)
* 父类型–>子类型
* 又被称为强制类型转换【需要强制类型转换符】
* 需要注意的是无论是向上还是向下转型,两者之间需要有继承关系
public class Animal{
public void move(){
System.out.println("动物在移动!");
}
}
public class Cat extends Animal {
public void move(){
System.out.println("猫在走猫步!");
}
public void catchMouse(){
System.out.println("猫在抓老鼠!");
}
}
public class Bird extends Animal{
//重写父类方法
public void move(){
System.out.println("鸟儿在飞翔!");
}
}
public class Test {
public static void main(String[] args) {
Animal a1 = new Animal();
a1.move();
Cat c1 = new Cat();
c1.move();
c1.catchMouse();
Bird b1 = new Bird();
b1.move();
//使用多态语法机制
/*
* 1、Cat is a Animal
* 2、new Cat()创建的对象类型是Cat,a2这个引用数据类型是Animal,
* 可见他们进行了类型转换、
* 3、子类转换到父类,称为向上转型,或者称为自动类型转换
*
* */
Animal a2 = new Cat();
//编译看左,运行看右
a2.move();
//因为编译阶段检测到a2的类型是Animal类型,其中没有catchmouse方法,导致静态绑定失败
//因此编译失败
/*
* 想要a2执行catchMouse()可以使用向下类型转换为Cat型
* --当调用的方法是子类型特有的,在父类型中不存在,必须使用向下转型
* */
Cat c2 = (Cat)a2; //强制向下转型
c2.catchMouse(); //猫抓老鼠!
/*
* 1、以下的程序编译是没有问题的,因为编译器检查到a3的数据类型是Animal
* Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型,
* 父类型转换成子类型叫做向下转型,语法合格
* 2、程序虽然编译通过了,但是程序在运行阶段会出现异常,因为JVM堆内存当中
* 真实存在的对象是Bird类型,Bird对象无法转换为Cat对象,因为两者之间没有任何继承关系
* 此时出现的著名的异常:
* java.lang.ClassCastException
* 类型转换异常,这种异常总是在“向下转型”的时候发生
* */
// Animal a3 = new Bird();
// Cat c3 = (Cat)a3;
/*
* 1、以上异常只有在强制类型转换的时候会发生,也就是向下转型存在隐患(编译通过,但是运行出错!)
* 2、向上转型只要编译通过,运行一定不会出错:Animal a = new Cat();
* 3、向下转型编译通过,运行可能错误
* 4、如何避免向下转型的异常呢?
* --使用instanceof运算符可以避免
* 5、instanceof运算符的使用:
* 5.1语法格式
* --(引用 instanceof 数据类型)
* 5.2以上运算符的执行结果是布尔类型
* 5.3true和false结果
* 假设:(a instanceof Animal)
* -true表示:a这个引用指向的对象是一个Animal类型
* -false表示:a这个引用指向的对象不是一个Animal类型
* 6、java规范要求:在强制类型转换之前建议使用instanceof运算符进行判断
* */
// Animal a3 = new Bird();
// Cat c3 = (Cat)a3;
Animal a3 = new Bird();
if (a3 instanceof Cat){
Cat c3 = (Cat) a3;
c3.catchMouse();
}
else if (a3 instanceof Bird){
Bird b2 = (Bird)a3;
b2.fly();
}
}
}
多态的作用
1、降低程序的耦合度,提高程序扩展力
2、能使用多态尽量使用多态
3、父类型引用指向子类型对象
核心:面向抽象编程,尽量不要面向具体编程