1.instanceof可以在运行阶段动态判断引用指向对象的类型
2.语法:(引用 instanceof 类型)
3.结果:true / false
4.c是一个引用,c变量保存了内存地址指向了堆中的对象
c instanceof Cat 的结果为true/false:
c引用指向的堆内存中的Java对象是/不是一个Cat
public class Applicaition {
public static void main(String[] args) {
Animal x = new Bird();
Animal y = new Cat();
if (x instanceof Bird){
Bird b = (Bird)x;
b.sing();
}else if (x instanceof Cat){
Cat c = (Cat)x;
c.catchMouse();
}
if (y instanceof Bird){
Bird b = (Bird)y;
b.sing();
}else if (y instanceof Cat){
Cat c = (Cat)y;
c.catchMouse();
}
}
}
public class Bird extends Animal {
//重写父类的move()方法
public void move(){
System.out.println("鸟儿在飞翔");
}
//也有自己特有的方法
public void sing(){
System.out.println("鸟儿在歌唱");
}
}
public class Cat extends Animal {
public void move(){
System.out.println("猫在跑");
}
public void catchMouse(){
System.out.println("猫在抓老鼠");
}
}
public class Animal {
//重写是方法的重写,和属性无关
public void move(){
System.out.println("动物在奔跑");
}
}
结果
鸟儿在歌唱
猫在抓老鼠
//Object > String
//Object > Person > Teacher
//Object > Person > Student
//instanceof可以在运行阶段动态判断引用指向对象的类型
//运行阶段,堆内存实际创建的对象是Student对象
Object obj = new Student();
System.out.println(obj instanceof Student);//true
System.out.println(obj instanceof Person);//true
System.out.println(obj instanceof Object);//true
System.out.println(obj instanceof Teacher);//false
System.out.println(obj instanceof String);//false
Person per = new Student();
System.out.println(per instanceof Student);//true
System.out.println(per instanceof Person);//true
System.out.println(per instanceof Object);//true
System.out.println(per instanceof Teacher);//false
//System.out.println(per instanceof String);//编译报错
Student stu = new Student();
System.out.println(stu instanceof Student);//true
System.out.println(stu instanceof Person);//true
System.out.println(stu instanceof Object);//true
//System.out.println(stu instanceof Teacher);//编译报错
//System.out.println(stu instanceof String);//编译报错
多态、转型和instanceof总结:
1.多态:多种形态,多种状态,编译和运行有两个不同的状态。
编译器叫做静态绑定,运行期叫做动态绑定。
Animal a = new Cat();
a.move();
编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move()方法
找到了绑定,编译通过。但是运行时和底层堆内存中的实际对象有关
真正执行的时候会自动调用“堆内存中真实对象”的相关方法
2.多态的典型代码:父类的引用指向子类的对象
3.向上转型和向下转型的概念:
向上转型:子---->父 (upcasting)
又称为自动类型转换 Animal a = new Cat();
向下转型:父---->子 (downcasting)
又称为强制类型转换 Cat c = (Cat)a; 需要添加强制类型转换符
4.什么时候需要向下转型?
需要调用或者执行子类对象中特有的方法
需要进行向下转型,才可以调用。
5.向下转型有风险吗?
容易出现ClassCastException(类型转换异常)
6.怎么避免?
instanceof运算符,可以在程序运行阶段动态的判断某个引用指向的对象是否为某一种类型
7.向下转型之前一定要确定 它们之间必须有继承关系,这样编译器就不会报错。