有了对象的多态后, 父类的引用不能直接调用子类特有的属性和方法,但是内存中是有子类特有的属性和方法的,如果想知道这个引用具体是哪个对象,怎么做呢?
对于基本数据类型,我们知道有自动类型提升和强制类型转换,那对于引用数据类型,对应的分别是向上转型和向下转型,向上转型其实就是多态了,向下转型就是将父类对象的引用转换为子类对象的引用,从而使用子类对象的应用可以调用子类的方法。
向下转型可能发生异常,比如下面的这段代码,发生异常ClassCastException
Person p = new Man();
Man m = (Man)p;
m.smooking();
//java.lang.ClassCastException
Women w = (Women)p;
w.goShop();
为了解决以上问题,引入了instanceof关键字
a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
使用情境:为了避免在向下转型时出现ClassCastException的异常,在向下转型之前,先
进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
如果 a instanceof A返回true,a instanceof B也返回true,那么类A和类B存在字符类关系。
开发中向下转型用的少, 用的最多的是向上转型
//Person.java
package com.ylaihui.oop8;
public class Person {
public void walk(){
System.out.println("Person walk()....");
}
}
//Man.java
package com.ylaihui.oop8;
public class Man extends Person {
public void smooking(){
System.out.println("Man smooking()...");
}
}
//Women.java
package com.ylaihui.oop8;
public class Women extends Person {
public void goShop(){
System.out.println("Women goShop()...");
}
}
//PersonTest.java
package com.ylaihui.oop8;
public class PersonTest {
public static void main(String[] args) {
Person p = new Man();
Man m = (Man)p;
m.smooking();
// java.lang.ClassCastException
// Women w = (Women)p;
// w.goShop();
// 为了解决以上异常, 使用 instanceof 判断
if(p instanceof Man) {
Man m1 = (Man)p;
m.smooking();
}
if(p instanceof Women) {
Women w1 = (Women)p;
w1.goShop();
}
if(p instanceof Person) {
System.out.println("p is Person");
}
if(p instanceof Object) {
System.out.println("p is Object");
}
}
}
运行结果
Man smooking()...
Man smooking()...
p is Person
p is Object