Java多态要满足3个条件:
1. 继承
2. 方法重写
3. 父类引用指向子类型对象(向上转型)
Animal.java
public class Animal{
public void eat(){
System.out.println(“动物在吃!”);
}
}
//----------------------
Cat.java
public class Cat extends Animal{
//重写方法eat
public void eat(){
System.out.println(“猫吃鱼!”);
}
//子类方法move
public void move(){
System.out.println(“猫走猫步!”);
}
}
//-----------------------
Dog.java
public class Dog extends Animal{
//重写
public void eat(){
System.out.println(“狗啃骨头!”);
}
}
/*
关于java语言中的向上转型和向下转型
1. 向上转型(upcasting):子--->父
2. 向下转型(downcasting):父--->子
注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系。
*/
Test.java
public class Test{
public static void main(String[] args){
/*
向上转型:自动类型转换
父类型引用指向子类型对象
程序分两个阶段:编译阶段和运行阶段
1.程序编译阶段只知道a1是一个Animal类型
2.程序在运行的时候堆中的实际对象是Cat类型
*/
Animal a1 = new Cat(); //自动类型转换
/*
1.程序在编译阶段:a1被编译器看做Animal类型
所以程序在编译阶段a1引用绑定的是Animal类中的eat方法(静态绑定)。
2.程序在运行的时候堆中的对象实际上是Cat类型,而Cat类已经重写了eat方法,所以程序在运行阶段对象绑定的方法是Cat中的eat方法(动态绑定)。
*/
a1.eat(); //猫吃鱼
//向下转型:强制类型转换
Animal a2 = new Cat(); //向上转型
/*
要执行a2.move方法,怎么做?
编译不通过(静态绑定的是Animal中的move,然而没有),解决方法:只能强制类型转换
*/
//a2.move();
Cat c1 = (Cat)a2;//强制类型转换
c1.move();
//判断以下程序是否正确?
Animal a3 = new Dog();
//Cat c2 = (Cat) a3;
//编译通过,运行不通过,报错 java.lang.ClassCastException
//所以,在强制类型转换的时候程序是存在风险的!
//为了避免ClassCastException的发生,java引入instanceof运算符
/*
用法:
1. instanceof运算符的运算结果是boolean类型
2.(引用 instanceof 类型)--->true/false
例如:(a instanceof Cat)如果结果是true,则a引用指向堆中的java对象是Cat类型
*/
Animal a4 = new Dog();
System.out.println(a4 instanceof Cat);//false
//推荐:在做向下转型的时候要使用instanceof运算符判断
if(a4 instanceof Cat){
Cat c2 = (Cat)a4;
}
}
}